openapi: 3.1.0 info: title: GESMO API v2 description: >- Public REST API for the GESMO / Gesvision ERP. Dates: ISO 8601 with the business time zone offset (ADR-007). Amounts: JSON numbers with 2 decimals HALF_UP (ADR-008). Pagination: skip/limit with a hard cap of 200 per page. contact: name: GESMO Team version: v2 servers: - url: / description: Current host security: - bearerAuth: [] tags: - name: Calendar Equipments description: Countable equipments for scheduling configuration. - name: Scheduling Events description: Booking of appointments through the canonical scheduling engine. - name: Views description: AG Grid view definitions and server-side row data for the SPA UI. - name: Block Slots description: Calendar and employee availability blocks. - name: Schema description: Field catalog discovery for the SPA UI. Returns non-INTERNAL fields from the FieldDef registry. - name: Coupon Types description: Discount coupon type catalog (TipoPin / ges_pin_tipo). - name: Payment Methods description: Create, read, update and delete payment methods (FormaDePago). - name: Custom Field Definitions description: Tenant catalog of user-defined custom fields (which fields exist per feature, their type, validation and presentation). Values travel in each entity's `customFields` list. - name: Visual Therapy Templates description: Visual therapy exercise templates (EjercicioTerapiaVisualPlantilla / ges_optica_ejer_terapiavisual_plantilla). - name: Departments description: Employee departments (departamentos de empleado). - name: Item Types description: Item classification and ledger mappings (TipoArticulo) - name: Service Catalog description: Bookable services, variations and add-ons. - name: Card Types description: Payment card brand catalog (TipoTarjeta). - name: Customers description: Create, read, update and delete customers (clientes / terceros) - name: Payment Terms description: Create, read, update and delete payment terms (CondicionPago). - name: Warehouse Types description: Branch / store types (TiendaTipoTienda). - name: SAT Mexico Configuration description: Company-scoped singleton configuration for Mexico SAT (CFDI). - name: Sales Quotes description: Create, read, update and delete customer sales quotes (presupuestos emitidos) - name: Chile SII Configuration description: Company-scoped singleton configuration for Chile SII e-invoicing. - name: Appointment Services description: Services associated to appointment types (servicios de tipo de cita). - name: Customer Profiles description: Default commercial terms catalog applied to customers (PerfilCliente). - name: Origin Types description: Claim origin types (ReclamoTipoOrigen / ges_reclamo_tipo_origen). - name: Staff Schedules description: Worker / staff schedules for scheduling configuration. - name: Cancellation Causes description: Cancellation causes (CausaAnulacion / causas de anulaci├│n). - name: Calendar Groups description: Calendar groups for scheduling configuration. - name: Calendar Rooms description: Bookable rooms for scheduling configuration. - name: Sales Credit Notes description: Create and query customer sales credit notes (notas de cr├®dito / abonos emitidos) - name: Employee Positions description: Employee store positions (posiciones de empleado). - name: Free Slots description: Availability computed by the canonical scheduling engine. - name: Series description: Document numbering series (Serie) per company and document family. - name: Appointments description: Calendar appointments / events (citas). - name: Visit Reasons description: Optical / commercial visit motives (MotivoVisita). - name: Inventory Entries description: Manual inventory entries (incoming stock adjustments). - name: Equivalence Surcharge Types description: Equivalence surcharge rate catalog (TipoRE / recargo de equivalencia) - name: Scheduling Calendars description: GHL-like calendar configuration (types, teamMembers, openHours, policies). - name: User Invitations description: Pending back-office user invitations. - name: Journal Entries description: Accounting journal entries (con_asientos / con_movimiento). - name: Sales Invoices description: Create, read, update and delete customer sales invoices (facturas emitidas) - name: Incoming Payments description: Create, read, update and delete incoming payments (cobros) - name: Inventory Counts description: Inventory counts (stock validation) with two-phase finalisation. - name: Pricing description: Stateless sales price resolution (tariffs, discounts, insurer conditions) for document forms. No side effects. - name: Categories description: Catalog categories (categorias), including tree traversal. - name: Sales Orders description: Create, read, update and delete customer sales orders (pedidos de cliente) - name: Solution Types description: Claim solution types (ReclamoTipoSolucion / ges_reclamo_tipo_solucion). - name: Purchase Invoices description: Create, read, update and delete supplier purchase invoices (facturas recibidas) - name: Collections description: Catalog collections (lineas de producto) ÔÇö segment which products are sold per branch. - name: Appointment Notes description: Free-text notes attached to an appointment. - name: Price Lists description: 'Price lists (tarifas): base cards (TB), factor cards (TBF), discount cards (DTO) and combos (COM), with per-product entries, discount rules and combo conditions.' - name: Products description: >- Catalog products (modelos) and their SKU-level variants (productos). Exposes the same surface as the legacy modeloDialog2 form. This is the only catalog resource that represents an actual sellable item. - name: Catalogs description: Dynamic enum catalogs and entity lookups consumed by AG Grid Set Filters and form autocompletes/selects. - name: Users description: Back-office user management (identity via auth-service + ERP enrichment). - name: Notes description: Polymorphic notes attached to customers or customer profiles. - name: Document Control Configuration description: Company-scoped singleton configuration for document and payment control. - name: Document Statuses description: Custom document statuses (EstadoDocumento / estados del documento). - name: Remittances description: SEPA direct-debit remittances (remesas). - name: Inventory Exits description: Manual inventory exits (outgoing stock adjustments). - name: Purchase Orders description: Create, read, update and delete supplier purchase orders (pedidos a proveedor) - name: Brands description: Catalog brands (marcas). - name: Solutions description: Claim solution configurations (ReclamoTipoReclamoSolucion / ges_reclamo_solucion). - name: Product Labels description: Catalog of product-label formats (etiquetas) and per-user favourites. - name: Claim Causes description: Claim causes (ReclamoCausante / ges_reclamo_causante). - name: Users description: SSRM view for the users grid. - name: Verifactu Configuration description: Company-scoped singleton configuration for VeriFactu. - name: Groups description: Catalog groups (grupos). - name: Outgoing Payments description: Create, read, update and delete outgoing payments (pagos a proveedor) - name: Claim Types description: Claim types (ReclamoTipoReclamo / ges_reclamo_tipo_reclamo) with nested solution configurations. - name: Calendars description: Scheduling calendars (calendarios). - name: Service Locations description: Branch booking profiles. - name: Appointment Types description: Appointment types (tipos de cita). - name: Accounting Accounts description: Company chart of accounts (CuentaContable / PGC) - name: Stock description: Stock snapshots per variant and warehouse. - name: Ranges description: Catalog ranges (gamas) ÔÇö secondary cross-cutting product classification. - name: Sales Delivery Notes description: Create, read, update and delete customer sales delivery notes (albaranes de entrega) - name: Return Causes description: Return causes (CausaDevolucion / causas de devoluci├│n). - name: Service Categories description: Bookable service categories. - name: Product Variants description: SKU-level product operations. The contextual search powers the document-form product panel; prices returned are informational. - name: Activities description: Accounting activities (con_actividad) for invoice classification. - name: Campaigns description: Catalog campaigns (campanias). - name: Purchase Delivery Notes description: Create, read, update and delete supplier purchase delivery notes (albaranes recibidos) - name: Service Bookings description: Multi-service appointment bookings. - name: Vat Types description: Company VAT rate catalog (TipoIVA) - name: Preferences description: 'Per-user preferences: default plantilla per grid feature, expanded listings, default dashboard.' - name: Cash Closes description: Cash register closes (cierres de caja). - name: Loyalty Wallets description: Loyalty points wallets (CarteraPuntos). - name: Associated Contact Types description: Relationship types between customers and associated contacts (TipoContactoAsociado). - name: Optical Orders description: >- Optical orders (encargos): workshop work orders for prescription eyewear and contact lenses. Each order holds patient data, frame geometry, per-eye prescription and bookkeeping links to invoices, customer orders, supplier orders and production orders. paths: /api/v2/warehouse-types/{id}: get: tags: - Warehouse Types summary: Get warehouse type by ID description: Returns a single warehouse type by its primary key. operationId: getById parameters: - name: id in: path description: Warehouse type ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Warehouse type found content: '*/*': schema: $ref: '#/components/schemas/WarehouseTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Warehouse type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Warehouse Types summary: Update warehouse type description: Full replacement of an existing warehouse type. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update parameters: - name: id in: path description: Warehouse type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/WarehouseTypeDocument' required: true responses: '200': description: Warehouse type updated content: '*/*': schema: $ref: '#/components/schemas/WarehouseTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Warehouse type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Warehouse Types summary: Delete warehouse type description: Deletes a warehouse type. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete parameters: - name: id in: path description: Warehouse type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Warehouse type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Warehouse type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Warehouse Types summary: Merge-patch warehouse type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch parameters: - name: id in: path description: Warehouse type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Warehouse type patched content: '*/*': schema: $ref: '#/components/schemas/WarehouseTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Warehouse type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visual-therapy-templates/{id}: get: tags: - Visual Therapy Templates summary: Get visual therapy template by ID description: Returns a single visual therapy exercise template by its primary key. operationId: getById_1 parameters: - name: id in: path description: Visual therapy template ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Visual therapy template found content: '*/*': schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visual therapy template not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Visual Therapy Templates summary: Update visual therapy template description: Full replacement of an existing visual therapy exercise template. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_1 parameters: - name: id in: path description: Visual therapy template ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' required: true responses: '200': description: Visual therapy template updated content: '*/*': schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visual therapy template not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Visual Therapy Templates summary: Delete visual therapy template description: Deletes a visual therapy exercise template. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_1 parameters: - name: id in: path description: Visual therapy template ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Visual therapy template deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visual therapy template not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Visual Therapy Templates summary: Merge-patch visual therapy template description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_1 parameters: - name: id in: path description: Visual therapy template ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Visual therapy template patched content: '*/*': schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visual therapy template not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visit-reasons/{id}: get: tags: - Visit Reasons summary: Get visit reason by ID description: Returns a single visit reason by its primary key. operationId: getById_2 parameters: - name: id in: path description: Visit reason ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Visit reason found content: '*/*': schema: $ref: '#/components/schemas/VisitReasonDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visit reason not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Visit Reasons summary: Update visit reason description: Full replacement of an existing visit reason. operationId: update_2 parameters: - name: id in: path description: Visit reason ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/VisitReasonDocument' required: true responses: '200': description: Visit reason updated content: '*/*': schema: $ref: '#/components/schemas/VisitReasonDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visit reason not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Visit Reasons summary: Delete visit reason description: Deletes a visit reason. operationId: delete_2 parameters: - name: id in: path description: Visit reason ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Visit reason deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visit reason not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Visit Reasons summary: Merge-patch visit reason description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_2 parameters: - name: id in: path description: Visit reason ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Visit reason patched content: '*/*': schema: $ref: '#/components/schemas/VisitReasonDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Visit reason not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/{viewId}: get: tags: - Views summary: Get the metadata of a grid view description: >- Returns columns, default sort, capabilities, actions and the user's persisted UI state. The view is built from the FieldDef catalog when the legacy plantilla is not configured (`{feature}-main` always works), and overridden by the user's plantilla when one exists. Cached for 5 minutes per the contract. operationId: getViewDefinition parameters: - name: viewId in: path description: Registered view identifier required: true schema: type: string example: brands-main responses: '200': description: View definition content: '*/*': schema: $ref: '#/components/schemas/ViewDefinition' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the entity's read permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Views summary: Save the column layout of a view description: >- Persists the column selection (order + width). The list is the visible column set; the backend keeps adding the PK, FK pair counterparts and ALWAYS_VISIBLE_COLUMN fields on the next GET. Both native (`name`, `code`...) and custom (`customFields.`) apiNames are accepted. With a **numeric viewId** the columns of THAT template are updated (the "Save" button of the template bar); the caller needs `canEdit` on it ÔÇö owner or EDITAR_PLANTILLASGLOBALES ÔÇö and a private template of another user answers 404. Unknown apiNames are rejected with 400 on named templates. **DEPRECATED (slug form)**: `PUT` on `{featureType}-main` still performs the historical implicit upsert of the user's un-named plantilla, but it is deprecated in favour of named templates (`POST /api/v2/views` + `PUT /api/v2/views/{plantillaId}`). It will start answering 400 once the SPA migrates to the template bar. operationId: saveViewLayout parameters: - name: viewId in: path description: 'Registered view identifier: slug or numeric template id' required: true schema: type: string example: brands-main requestBody: content: application/json: schema: $ref: '#/components/schemas/ViewLayoutUpdateRequest' required: true responses: '204': description: Layout saved '400': description: Invalid payload, unknown apiNames on a named template, or feature without a writable plantilla content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing edit permission on the entity, or no edit rights over the referenced template content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered (or private template of another user) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Views summary: Delete a view template description: >- Deletes a named template and sweeps every reference: the template selection of ALL users (`UserPreferencesDocument.viewTemplates` stops listing it, so they fall back to the system view) and the per-user grid states persisted for this viewId. Idempotent: deleting an id that no longer exists returns 204. The system view is not deletable (400). operationId: delete_3 parameters: - name: viewId in: path description: Numeric id of a persisted template required: true schema: type: string example: 1042 responses: '204': description: Template deleted (or it no longer existed) '400': description: viewId is the system view or not a named template content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Caller has no delete rights over this template content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Private template of another user content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Views summary: Rename or change visibility of a view template description: >- Merge-patch of `{ name?, visibility? }`; omitted fields are left untouched. Columns are NOT patched here ÔÇö they go through the existing `PUT /api/v2/views/{viewId}`. The system view (`{featureType}-main`) is not patchable (400). A private template of another user answers 404 (not 403). operationId: patch_3 parameters: - name: viewId in: path description: Numeric id of a persisted template required: true schema: type: string example: 1042 requestBody: content: application/json: schema: $ref: '#/components/schemas/ViewTemplatePatchRequest' required: true responses: '200': description: Updated template summary content: '*/*': schema: $ref: '#/components/schemas/ViewTemplateSummary' '400': description: viewId is the system view / not a named template, or invalid body content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Caller has no edit rights over this template content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Template does not exist (or is a private template of another user) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: A template with the same name already exists for this feature and owner content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/{viewId}/user-state: put: tags: - Views summary: Persist the user's UI state for a view description: >- Body is the full `UserGridState`. The backend stores it verbatim associated to (userId, viewId) and overwrites the existing state. `filterModel` is OPAQUE: never interpreted by the backend. Max payload ~32 KB. operationId: saveViewUserState parameters: - name: viewId in: path description: Registered view identifier required: true schema: type: string example: brands-main requestBody: content: application/json: schema: $ref: '#/components/schemas/UserGridState' required: true responses: '200': description: User state saved content: '*/*': schema: type: object additionalProperties: type: boolean '400': description: Invalid JSON or payload too large content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Views summary: Reset the user's UI state for a view description: Idempotent. Returns 204 whether or not the user had a persisted state. After this the next GET returns the default layout. operationId: deleteViewUserState parameters: - name: viewId in: path description: Registered view identifier required: true schema: type: string example: brands-main responses: '204': description: User state cleared '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/vat-types/{id}: get: tags: - Vat Types summary: Get VAT type by ID description: Returns the VAT type including warehouseOverrides and associatedAccounts. operationId: getById_3 parameters: - name: id in: path description: VAT type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: VAT type found content: '*/*': schema: $ref: '#/components/schemas/VatTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: VAT type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Vat Types summary: Update VAT type description: >- Full replacement. On update, null warehouseOverrides/associatedAccounts leaves existing children untouched; [] clears; non-empty list replaces. vatRatePurchase requires differentPurchaseSaleVat=true (header and each warehouse row). operationId: update_3 parameters: - name: id in: path description: VAT type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/VatTypeDocument' required: true responses: '200': description: VAT type updated content: '*/*': schema: $ref: '#/components/schemas/VatTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: VAT type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Vat Types summary: Delete VAT type description: Deletes the VAT type. If-Match is accepted but ignored (TipoIVA is not versioned). operationId: delete_4 parameters: - name: id in: path description: VAT type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: VAT type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: VAT type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Vat Types summary: Merge-patch VAT type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_4 parameters: - name: id in: path description: VAT type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: VAT type patched content: '*/*': schema: $ref: '#/components/schemas/VatTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: VAT type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{userId}/preferences: get: tags: - Preferences summary: Get a user's preferences description: Returns the preferences of the given user. Permitted when the caller is the same user, or holds `VER_USUARIOSPREF`. operationId: getUserPreferences parameters: - name: userId in: path description: Identifier of the user whose preferences are requested. required: true schema: type: integer format: int64 example: 123 responses: '200': description: Preferences content: '*/*': schema: $ref: '#/components/schemas/UserPreferencesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Caller is not the target user and is missing `VER_USUARIOSPREF` content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Preferences summary: Update a user's preferences description: Updates the preferences of the given user. Permitted when the caller is the same user, or holds `EDITAR_USUARIOSPREF`. operationId: updateUserPreferences parameters: - name: userId in: path description: Identifier of the user whose preferences are updated. required: true schema: type: integer format: int64 example: 123 requestBody: content: application/json: schema: $ref: '#/components/schemas/UserPreferencesDocument' required: true responses: '200': description: Preferences content: '*/*': schema: $ref: '#/components/schemas/UserPreferencesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Caller is not the target user and is missing `EDITAR_USUARIOSPREF` content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solutions/{id}: get: tags: - Solutions summary: Get solution by ID description: Returns a single claim solution configuration by its primary key, including synthesized {@code actions} from legacy permission flags. operationId: getById_4 parameters: - name: id in: path description: Solution ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Solution found content: '*/*': schema: $ref: '#/components/schemas/SolutionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Solutions summary: Update solution description: Full replacement of an existing claim solution configuration. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_4 parameters: - name: id in: path description: Solution ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SolutionDocument' required: true responses: '200': description: Solution updated content: '*/*': schema: $ref: '#/components/schemas/SolutionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Solutions summary: Delete solution description: Deletes a claim solution configuration. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_5 parameters: - name: id in: path description: Solution ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Solution deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Solutions summary: Merge-patch solution description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_5 parameters: - name: id in: path description: Solution ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Solution patched content: '*/*': schema: $ref: '#/components/schemas/SolutionDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solution-types/{id}: get: tags: - Solution Types summary: Get solution type by ID description: Returns a single claim solution type by its primary key. operationId: getById_5 parameters: - name: id in: path description: Solution type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Solution type found content: '*/*': schema: $ref: '#/components/schemas/SolutionTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Solution Types summary: Update solution type description: Full replacement of an existing claim solution type. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_5 parameters: - name: id in: path description: Solution type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SolutionTypeDocument' required: true responses: '200': description: Solution type updated content: '*/*': schema: $ref: '#/components/schemas/SolutionTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Solution Types summary: Delete solution type description: Deletes a claim solution type. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_6 parameters: - name: id in: path description: Solution type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Solution type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Solution Types summary: Merge-patch solution type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_6 parameters: - name: id in: path description: Solution type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Solution type patched content: '*/*': schema: $ref: '#/components/schemas/SolutionTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Solution type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/series/{id}: get: tags: - Series summary: Get series by ID description: Returns a single numbering series by its primary key. The response carries a strong `ETag` header (always `"0"` ÔÇö Serie is not versioned). operationId: getById_6 parameters: - name: id in: path description: Series ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Series found content: '*/*': schema: $ref: '#/components/schemas/SeriesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Series not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Series summary: Update series description: >- Full replacement of an existing series. `documentKind` is immutable after create ÔÇö sending a different value returns 400. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö Serie is not versioned). operationId: update_6 parameters: - name: id in: path description: Series ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SeriesDocument' required: true responses: '200': description: Series updated content: '*/*': schema: $ref: '#/components/schemas/SeriesDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Series not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Series summary: Delete series description: Deletes a numbering series. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö Serie is not versioned). operationId: delete_7 parameters: - name: id in: path description: Series ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Series deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Series not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Series summary: Merge-patch series description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. `documentKind` cannot be changed via patch. operationId: patch_7 parameters: - name: id in: path description: Series ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Series patched content: '*/*': schema: $ref: '#/components/schemas/SeriesDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Series not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/locations/{id}: get: tags: - Service Locations summary: Get service location by ID operationId: getById_7 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceLocationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Service Locations summary: Update service location operationId: update_7 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceLocationDocument' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceLocationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Service Locations summary: Delete service location operationId: delete_8 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string responses: '204': description: No Content '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Service Locations summary: Merge-patch service location description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_8 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceLocationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/categories/{id}: get: tags: - Service Categories summary: Get service category by ID operationId: getById_8 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceCategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Service Categories summary: Update service category operationId: update_8 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceCategoryDocument' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceCategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Service Categories summary: Delete service category operationId: delete_9 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string responses: '204': description: No Content '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Service Categories summary: Merge-patch service category description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_9 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceCategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/catalog/{id}: get: tags: - Service Catalog summary: Get service by ID operationId: getById_9 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Service Catalog summary: Update service operationId: update_9 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceDocument' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Service Catalog summary: Delete service operationId: delete_10 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string responses: '204': description: No Content '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Service Catalog summary: Merge-patch service description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_10 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/bookings/{id}: get: tags: - Service Bookings summary: Get service booking by ID operationId: getById_10 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceBookingDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Service Bookings summary: Update service booking operationId: update_10 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string - name: overrideAvailability in: query required: false schema: type: boolean default: false - name: skipSchedulingNotice in: query required: false schema: type: boolean default: false requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceBookingDocument' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceBookingDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Service Bookings summary: Delete service booking operationId: delete_11 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string responses: '204': description: No Content '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Service Bookings summary: Merge-patch service booking description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_11 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/ServiceBookingDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/events/{id}: put: tags: - Scheduling Events summary: Reschedule an appointment description: >- Full replacement of an existing appointment, validated exactly like a creation. The appointment's own current interval is excluded from the occupancy, so moving it by five minutes does not collide with itself. Evento has no `OPTLOCK` column, so `If-Match` is accepted for API symmetry but ignored. operationId: updateSchedulingEvent parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 - name: If-Match in: header description: Accepted for API symmetry; ignored because Evento has no OPTLOCK column. required: false schema: type: string example: '3' - name: ignoreDateRange in: query description: >- Skips the calendar's booking window ÔÇö the minimum scheduling notice (`allowBookingAfter`) and the horizon (`allowBookingFor`). Every other availability rule still applies. Equivalent to GHL `ignoreDateRange`. Recorded on the appointment's `bookingLog`. required: false schema: type: boolean default: false example: false - name: ignoreFreeSlotValidation in: query description: >- Skips the availability check entirely, letting the counter overbook on purpose. The agenda is still locked, so concurrent writes stay serialised. Equivalent to GHL `ignoreFreeSlotValidation`. Recorded on the appointment's `bookingLog`. required: false schema: type: boolean default: false example: false requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentDocument' required: true responses: '200': description: Appointment rescheduled content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: The payload is valid but the engine does not offer that interval. The `detail` names the slots that were available that day. Retry with `ignoreFreeSlotValidation=true` to book it anyway. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Scheduling Events summary: Cancel an appointment description: > Cancels the appointment: its status becomes `CANCELLED` (`EstadoEvento.CANC`) and the row is preserved. This is deliberately not a physical delete. A cancelled appointment keeps the history of who booked what and when ÔÇö which is what makes a reschedule auditable ÔÇö and lets the CRM connector push the cancellation out instead of finding a dangling reference. The slot is released either way: the availability engine treats `CANCELLED` as free. Cancelling an already cancelled appointment succeeds and changes nothing. operationId: cancelSchedulingEvent parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 - name: If-Match in: header description: Accepted for API symmetry; ignored because Evento has no OPTLOCK column. required: false schema: type: string example: '3' responses: '204': description: Appointment cancelled '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/events/block-slots/{id}: get: tags: - Block Slots summary: Get block slot by ID description: Returns a single block slot by its primary key. operationId: getById_11 parameters: - name: id in: path description: Block slot ID required: true schema: type: integer format: int64 example: 12 responses: '200': description: Block slot found content: '*/*': schema: $ref: '#/components/schemas/BlockSlotDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Block slot not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Block Slots summary: Update block slot description: Full replacement of an existing block slot. The calendarId / employeeId exclusivity rule applies to the new state. operationId: update_11 parameters: - name: id in: path description: Block slot ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/BlockSlotDocument' required: true responses: '200': description: Block slot updated content: '*/*': schema: $ref: '#/components/schemas/BlockSlotDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Block slot not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Block Slots summary: Delete block slot description: Removes the block. Unlike appointments, a block has no history worth preserving, so this is a physical delete. operationId: delete_12 parameters: - name: id in: path description: Block slot ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Block slot deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Block slot not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Block Slots summary: Merge-patch block slot description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_12 parameters: - name: id in: path description: Block slot ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Block slot patched content: '*/*': schema: $ref: '#/components/schemas/BlockSlotDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Block slot not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/{id}: get: tags: - Scheduling Calendars summary: Get calendar by ID description: Returns a single calendar with the full GHL-like contract. operationId: getById_12 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 responses: '200': description: Calendar found content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Scheduling Calendars summary: Update calendar description: Full replacement of an existing calendar (GHL-like contract). operationId: update_12 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarDocument' required: true responses: '200': description: Calendar updated content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Scheduling Calendars summary: Delete calendar description: Deletes a calendar via the WAR command gateway. operationId: delete_13 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Calendar deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Scheduling Calendars summary: Merge-patch calendar description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_13 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Calendar patched content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/schedules/{id}: get: tags: - Staff Schedules summary: Get staff schedule by ID operationId: getById_13 parameters: - name: id in: path description: Staff schedule ID required: true schema: type: integer format: int64 example: 12 responses: '200': description: Staff schedule found content: '*/*': schema: $ref: '#/components/schemas/StaffScheduleDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Staff schedule not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Staff Schedules summary: Update staff schedule operationId: update_13 parameters: - name: id in: path description: Staff schedule ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/StaffScheduleDocument' required: true responses: '200': description: Staff schedule updated content: '*/*': schema: $ref: '#/components/schemas/StaffScheduleDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Staff schedule not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Staff Schedules summary: Delete staff schedule operationId: delete_14 parameters: - name: id in: path description: Staff schedule ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Staff schedule deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Staff schedule not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Staff Schedules summary: Merge-patch staff schedule description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_14 parameters: - name: id in: path description: Staff schedule ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Staff schedule patched content: '*/*': schema: $ref: '#/components/schemas/StaffScheduleDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Staff schedule not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/resources/rooms/{id}: get: tags: - Calendar Rooms summary: Get calendar room by ID operationId: getById_14 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: Calendar room found content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Calendar Rooms summary: Update calendar room operationId: update_14 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarResourceDocument' required: true responses: '200': description: Calendar room updated content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Calendar Rooms summary: Delete calendar room operationId: delete_15 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string responses: '204': description: Calendar room deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Calendar Rooms summary: Merge-patch calendar room description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_15 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Calendar room patched content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/resources/equipments/{id}: get: tags: - Calendar Equipments summary: Get calendar equipment by ID operationId: getById_15 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: Calendar equipment found content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Calendar Equipments summary: Update calendar equipment operationId: update_15 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarResourceDocument' required: true responses: '200': description: Calendar equipment updated content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Calendar Equipments summary: Delete calendar equipment operationId: delete_16 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string responses: '204': description: Calendar equipment deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Calendar Equipments summary: Merge-patch calendar equipment description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_16 parameters: - name: id in: path required: true schema: type: integer format: int64 - name: If-Match in: header required: false schema: type: string requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Calendar equipment patched content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/groups/{id}: get: tags: - Calendar Groups summary: Get calendar group by ID operationId: getById_16 parameters: - name: id in: path description: Calendar group ID required: true schema: type: integer format: int64 example: 12 responses: '200': description: Calendar group found content: '*/*': schema: $ref: '#/components/schemas/CalendarGroupDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Calendar Groups summary: Update calendar group operationId: update_16 parameters: - name: id in: path description: Calendar group ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarGroupDocument' required: true responses: '200': description: Calendar group updated content: '*/*': schema: $ref: '#/components/schemas/CalendarGroupDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Calendar Groups summary: Delete calendar group operationId: delete_17 parameters: - name: id in: path description: Calendar group ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Calendar group deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Calendar Groups summary: Merge-patch calendar group description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_17 parameters: - name: id in: path description: Calendar group ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Calendar group patched content: '*/*': schema: $ref: '#/components/schemas/CalendarGroupDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/appointments/{appointmentId}/notes/{noteId}: get: tags: - Appointment Notes summary: Get appointment note by ID operationId: getAppointmentNoteById parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 - name: noteId in: path description: Note ID required: true schema: type: integer format: int64 example: 7 responses: '200': description: Note found content: '*/*': schema: $ref: '#/components/schemas/AppointmentNoteDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found on that appointment content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Appointment Notes summary: Update appointment note description: Full replacement of an existing note. operationId: updateAppointmentNote parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 - name: noteId in: path description: Note ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentNoteDocument' required: true responses: '200': description: Note updated content: '*/*': schema: $ref: '#/components/schemas/AppointmentNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found on that appointment content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Appointment Notes summary: Delete appointment note operationId: deleteAppointmentNote parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 - name: noteId in: path description: Note ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Note deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found on that appointment content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Appointment Notes summary: Merge-patch appointment note description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patchAppointmentNote parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 - name: noteId in: path description: Note ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Note patched content: '*/*': schema: $ref: '#/components/schemas/AppointmentNoteDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found on that appointment content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-quotes/{id}: get: tags: - Sales Quotes summary: Get sales quote by ID description: >- Returns a single customer sales quote by its primary key, including line items and payments. Listing (`GET` without id) returns headers only. The response carries a strong `ETag` header with the current version. operationId: getById_17 parameters: - name: id in: path description: Sales quote ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Sales quote found content: '*/*': schema: $ref: '#/components/schemas/SalesQuoteDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales quote not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Sales Quotes summary: Update sales quote description: Full replacement of an existing customer sales quote. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_17 parameters: - name: id in: path description: Sales quote ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesQuoteDocument' required: true responses: '200': description: Sales quote updated content: '*/*': schema: $ref: '#/components/schemas/SalesQuoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales quote not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Sales Quotes summary: Delete sales quote description: Deletes a customer sales quote. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_18 parameters: - name: id in: path description: Sales quote ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Sales quote deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales quote not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Sales Quotes summary: Merge-patch sales quote description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_18 parameters: - name: id in: path description: Sales quote ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Sales quote patched content: '*/*': schema: $ref: '#/components/schemas/SalesQuoteDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales quote not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-orders/{id}: get: tags: - Sales Orders summary: Get sales order by ID description: >- Returns a single customer sales order by its primary key, including line items and payments. Listing (`GET` without id) returns headers only. The response carries a strong `ETag` header with the current version. operationId: getById_18 parameters: - name: id in: path description: Sales order ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Sales order found content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Sales Orders summary: Update sales order description: Full replacement of an existing customer sales order. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_18 parameters: - name: id in: path description: Sales order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/OrderDocument' required: true responses: '200': description: Sales order updated content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Sales Orders summary: Delete sales order description: Deletes a customer sales order. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_19 parameters: - name: id in: path description: Sales order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Sales order deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Sales Orders summary: Merge-patch sales order description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_19 parameters: - name: id in: path description: Sales order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Sales order patched content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-invoices/{id}: get: tags: - Sales Invoices summary: Get sales invoice by ID description: >- Returns a single customer sales invoice by its primary key. The response carries a strong `ETag` header with the current version for optimistic concurrency control. Returns 404 when the requested ID belongs to a purchase (issued=false) document. Honours `If-None-Match`: when the supplied ETag matches the current version on the server, the endpoint returns `304 Not Modified` without loading the full invoice detail graph. operationId: getById_19 parameters: - name: id in: path description: Sales invoice ID required: true schema: type: integer format: int64 example: 123 - name: If-None-Match in: header description: >- Conditional GET: send the ETag from a previous response (e.g. `"3"`) to ask the server to skip the body when nothing has changed. If the supplied version matches the current entity version the endpoint returns `304 Not Modified` with the ETag header and no body ÔÇö the SQL load for the detail graph is skipped entirely. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted, plus the wildcard `*` which matches any current version. required: false schema: type: string example: '3' responses: '200': description: Sales invoice found content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '304': description: Not Modified ÔÇö the client's `If-None-Match` ETag matches the current version content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Sales Invoices summary: Update sales invoice description: >- Full replacement of an existing customer sales invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control. The `issued` flag is forced to `true` server-side. Returns 404 when the requested ID belongs to a purchase document. operationId: update_19 parameters: - name: id in: path description: Sales invoice ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '200': description: Sales invoice updated content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Sales Invoices summary: Delete sales invoice description: Deletes a customer sales invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_20 parameters: - name: id in: path description: Sales invoice ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Sales invoice deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Sales Invoices summary: Merge-patch sales invoice description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_20 parameters: - name: id in: path description: Sales invoice ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Sales invoice patched content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-delivery-notes/{id}: get: tags: - Sales Delivery Notes summary: Get sales delivery note by ID description: >- Returns a single customer sales delivery note by its primary key, including line items and payments. Listing (`GET` without id) returns headers only. The response carries a strong `ETag` header with the current version. operationId: getById_20 parameters: - name: id in: path description: Sales delivery note ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Sales delivery note found content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Sales Delivery Notes summary: Update sales delivery note description: Full replacement of an existing customer sales delivery note. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_20 parameters: - name: id in: path description: Sales delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' required: true responses: '200': description: Sales delivery note updated content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Sales Delivery Notes summary: Delete sales delivery note description: Deletes a customer sales delivery note. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_21 parameters: - name: id in: path description: Sales delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Sales delivery note deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Sales Delivery Notes summary: Merge-patch sales delivery note description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_21 parameters: - name: id in: path description: Sales delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Sales delivery note patched content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-credit-notes/{id}: get: tags: - Sales Credit Notes summary: Get sales credit note by ID description: Returns a single customer sales credit note by its primary key. Returns `404` if the id refers to a regular (non-corrective) invoice. operationId: getById_21 parameters: - name: id in: path description: Sales credit note ID required: true schema: type: integer format: int64 example: 456 responses: '200': description: Sales credit note found content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales credit note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Sales Credit Notes summary: Update sales credit note description: Full replacement of a customer sales credit note. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_21 parameters: - name: id in: path description: Sales credit note ID required: true schema: type: integer format: int64 example: 456 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '200': description: Sales credit note updated content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales credit note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Sales Credit Notes summary: Delete sales credit note description: Deletes a customer sales credit note. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_22 parameters: - name: id in: path description: Sales credit note ID required: true schema: type: integer format: int64 example: 456 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Sales credit note deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales credit note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/return-causes/{id}: get: tags: - Return Causes summary: Get return cause by ID description: Returns a single return cause by its primary key. operationId: getById_22 parameters: - name: id in: path description: Return cause ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Return cause found content: '*/*': schema: $ref: '#/components/schemas/ReturnCauseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Return cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Return Causes summary: Update return cause description: Full replacement of an existing return cause. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_22 parameters: - name: id in: path description: Return cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ReturnCauseDocument' required: true responses: '200': description: Return cause updated content: '*/*': schema: $ref: '#/components/schemas/ReturnCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Return cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Return Causes summary: Delete return cause description: Deletes a return cause. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_23 parameters: - name: id in: path description: Return cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Return cause deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Return cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Return Causes summary: Merge-patch return cause description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_22 parameters: - name: id in: path description: Return cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Return cause patched content: '*/*': schema: $ref: '#/components/schemas/ReturnCauseDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Return cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/ranges/{id}: get: tags: - Ranges summary: Get range by ID description: Returns a single range by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_23 parameters: - name: id in: path description: Range ID required: true schema: type: integer format: int64 example: 8 responses: '200': description: Range found content: '*/*': schema: $ref: '#/components/schemas/RangeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Range not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Ranges summary: Update range description: Full replacement of an existing range. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_23 parameters: - name: id in: path description: Range ID required: true schema: type: integer format: int64 example: 8 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/RangeDocument' required: true responses: '200': description: Range updated content: '*/*': schema: $ref: '#/components/schemas/RangeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Range not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Ranges summary: Delete range description: Deletes a range. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_24 parameters: - name: id in: path description: Range ID required: true schema: type: integer format: int64 example: 8 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Range deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Range not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Ranges summary: Merge-patch range description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_23 parameters: - name: id in: path description: Range ID required: true schema: type: integer format: int64 example: 8 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Range patched content: '*/*': schema: $ref: '#/components/schemas/RangeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Range not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-orders/{id}: get: tags: - Purchase Orders summary: Get purchase order by ID description: Returns a single purchase order by its primary key, including line items and payments. Returns 404 when the requested ID belongs to a sales (issued) document. operationId: getById_24 parameters: - name: id in: path description: Purchase order ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Purchase order found content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Purchase Orders summary: Update purchase order description: Full replacement of an existing purchase order. Send the `If-Match` header with the current ETag for optimistic concurrency control. The `issued` flag is forced to `false` server-side. operationId: update_24 parameters: - name: id in: path description: Purchase order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/OrderDocument' required: true responses: '200': description: Purchase order updated content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Purchase Orders summary: Delete purchase order description: Deletes a purchase order. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_25 parameters: - name: id in: path description: Purchase order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Purchase order deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Purchase Orders summary: Merge-patch purchase order description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_24 parameters: - name: id in: path description: Purchase order ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Purchase order patched content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-invoices/{id}: get: tags: - Purchase Invoices summary: Get purchase invoice by ID description: Returns a single purchase invoice by its primary key. Returns 404 when the requested ID belongs to a sales (issued) document. operationId: getById_25 parameters: - name: id in: path description: Purchase invoice ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Purchase invoice found content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Purchase Invoices summary: Update purchase invoice description: Full replacement of an existing purchase invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control. The `issued` flag is forced to `false` server-side. operationId: update_25 parameters: - name: id in: path description: Purchase invoice ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '200': description: Purchase invoice updated content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Purchase Invoices summary: Delete purchase invoice description: Deletes a purchase invoice. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_26 parameters: - name: id in: path description: Purchase invoice ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Purchase invoice deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Purchase Invoices summary: Merge-patch purchase invoice description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_25 parameters: - name: id in: path description: Purchase invoice ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Purchase invoice patched content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-delivery-notes/{id}: get: tags: - Purchase Delivery Notes summary: Get purchase delivery note by ID description: Returns a single purchase delivery note by its primary key, including line items and payments. Returns 404 when the requested ID belongs to a sales (issued) document. operationId: getById_26 parameters: - name: id in: path description: Purchase delivery note ID required: true schema: type: integer format: int64 example: 789 responses: '200': description: Purchase delivery note found content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Purchase Delivery Notes summary: Update purchase delivery note description: Full replacement of an existing purchase delivery note. Send the `If-Match` header with the current ETag for optimistic concurrency control. The `issued` flag is forced to `false` server-side. operationId: update_26 parameters: - name: id in: path description: Purchase delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' required: true responses: '200': description: Purchase delivery note updated content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Purchase Delivery Notes summary: Delete purchase delivery note description: Deletes a purchase delivery note. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_27 parameters: - name: id in: path description: Purchase delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Purchase delivery note deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Purchase Delivery Notes summary: Merge-patch purchase delivery note description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_26 parameters: - name: id in: path description: Purchase delivery note ID required: true schema: type: integer format: int64 example: 789 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Purchase delivery note patched content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Purchase delivery note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/products/{id}: get: tags: - Products summary: Get product by ID description: >- Returns a single product with the FULL graph: header fields, variants, product-level and variant-level custom field values, stock summary per branch and supplier prices. Carries a strong `ETag` header with the current version. operationId: getById_27 parameters: - name: id in: path description: Product ID required: true schema: type: integer format: int64 example: 4231 responses: '200': description: Product found content: '*/*': schema: $ref: '#/components/schemas/ProductDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Product not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Products summary: Update product description: >- Full replacement of an existing product and its variants. Variants whose `id` is present in the payload are updated in place; new variants (no `id`) are created; existing variants whose id is absent from the payload are deleted. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_27 parameters: - name: id in: path description: Product ID required: true schema: type: integer format: int64 example: 4231 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ProductDocument' required: true responses: '200': description: Product updated content: '*/*': schema: $ref: '#/components/schemas/ProductDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Product not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Products summary: Delete product description: >- Deletes a product and all of its variants (cascade). Send the `If-Match` header with the current ETag for optimistic concurrency control. Products referenced by sales documents cannot be deleted and return `409 Conflict`. operationId: delete_28 parameters: - name: id in: path description: Product ID required: true schema: type: integer format: int64 example: 4231 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Product deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Product not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. Also returned when the product is referenced by sales documents. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Products summary: Merge-patch product description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. For variant collections, use the variant `id` to update existing rows; the merge keeps any field not mentioned in the patch. operationId: patch_27 parameters: - name: id in: path description: Product ID required: true schema: type: integer format: int64 example: 4231 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Product patched content: '*/*': schema: $ref: '#/components/schemas/ProductDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Product not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}: get: tags: - Price Lists summary: Get price list by ID description: Returns a single price list including branch schedules, payment method constraints and card types. The response carries an `ETag` header. operationId: getById_28 parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Price list found content: '*/*': schema: $ref: '#/components/schemas/PriceListDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Price Lists summary: Update price list description: >- Full replacement of an existing price list. Also finalises a draft: the server clears `draft` on every update. `branchSchedules` and `paymentMethodIds` follow the collection contract: null = untouched, [] = clear, non-empty = full replacement. operationId: update_28 parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListDocument' required: true responses: '200': description: Price list updated content: '*/*': schema: $ref: '#/components/schemas/PriceListDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Price Lists summary: Delete price list description: Deletes a price list (also used to cancel a draft created by `POST /new`). operationId: delete_29 parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Price list deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Price Lists summary: Merge-patch price list description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_28 parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Price list patched content: '*/*': schema: $ref: '#/components/schemas/PriceListDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/entries/{entryId}: put: tags: - Price Lists summary: Update price list entry description: Updates the value fields of an entry (price, discountPercent, factor, finalPrice, vatIncluded, reference). The target product is immutable. operationId: updatePriceListEntry parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: entryId in: path description: Entry ID required: true schema: type: integer format: int64 example: 1201 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListEntryDocument' required: true responses: '200': description: Entry updated content: '*/*': schema: $ref: '#/components/schemas/PriceListEntryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list or entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Price Lists summary: Delete price list entry description: Deletes one entry (product price or discount rule row). operationId: deletePriceListEntry parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: entryId in: path description: Entry ID required: true schema: type: integer format: int64 example: 1201 responses: '204': description: Entry deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list or entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/combo-conditions/{conditionId}: put: tags: - Price Lists summary: Update price list combo condition description: Updates name, quantity, price/discount and VAT flags of a combo condition. The purchase/sale side is immutable. operationId: updatePriceListComboCondition parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: conditionId in: path description: Combo condition ID required: true schema: type: integer format: int64 example: 12 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListComboConditionDocument' required: true responses: '200': description: Combo condition updated content: '*/*': schema: $ref: '#/components/schemas/PriceListComboConditionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list or combo condition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Price Lists summary: Delete price list combo condition description: Deletes a combo condition. Fails when the condition is referenced by documents already invoiced with the combo. operationId: deletePriceListComboCondition parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: conditionId in: path description: Combo condition ID required: true schema: type: integer format: int64 example: 12 responses: '204': description: Combo condition deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list or combo condition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-terms/{id}: get: tags: - Payment Terms summary: Get payment term by ID description: Returns a single payment term by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_29 parameters: - name: id in: path description: Payment term ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Payment term found content: '*/*': schema: $ref: '#/components/schemas/PaymentTermDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment term not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Payment Terms summary: Update payment term description: Full replacement of an existing payment term. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_29 parameters: - name: id in: path description: Payment term ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentTermDocument' required: true responses: '200': description: Payment term updated content: '*/*': schema: $ref: '#/components/schemas/PaymentTermDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment term not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Payment Terms summary: Delete payment term description: Deletes a payment term. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_30 parameters: - name: id in: path description: Payment term ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Payment term deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment term not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Payment Terms summary: Merge-patch payment term description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_29 parameters: - name: id in: path description: Payment term ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Payment term patched content: '*/*': schema: $ref: '#/components/schemas/PaymentTermDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment term not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-methods/{id}: get: tags: - Payment Methods summary: Get payment method by ID description: >- Returns a single payment method by its primary key, including the per-company ledger account mapping (`associatedAccounts`). The response carries a strong `ETag` header with the current version. operationId: getById_30 parameters: - name: id in: path description: Payment method ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Payment method found content: '*/*': schema: $ref: '#/components/schemas/PaymentMethodDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment method not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Payment Methods summary: Update payment method description: >- Full replacement of an existing payment method. Send the `If-Match` header with the current ETag for optimistic concurrency control. `associatedAccounts` follows collection semantics: null leaves the ledger mapping untouched, [] clears it, a non-empty list replaces it. operationId: update_30 parameters: - name: id in: path description: Payment method ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentMethodDocument' required: true responses: '200': description: Payment method updated content: '*/*': schema: $ref: '#/components/schemas/PaymentMethodDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment method not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Payment Methods summary: Delete payment method description: >- Deletes a payment method. Send the `If-Match` header with the current ETag for optimistic concurrency control. Payment methods that are referenced by existing payments cannot be deleted (`409`). operationId: delete_31 parameters: - name: id in: path description: Payment method ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Payment method deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment method not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Payment Methods summary: Merge-patch payment method description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_30 parameters: - name: id in: path description: Payment method ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Payment method patched content: '*/*': schema: $ref: '#/components/schemas/PaymentMethodDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Payment method not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/outgoing-payments/{id}: get: tags: - Outgoing Payments summary: Get outgoing payment by ID description: Returns a single outgoing payment by its primary key. Returns 404 when the requested ID belongs to an incoming payment. operationId: getById_31 parameters: - name: id in: path description: Outgoing payment ID required: true schema: type: integer format: int64 example: 321 responses: '200': description: Outgoing payment found content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Outgoing payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Outgoing Payments summary: Update outgoing payment description: Full replacement of an existing outgoing payment. The `If-Match` header is accepted for API symmetry but is not enforced (Cobro has no OPTLOCK). operationId: update_31 parameters: - name: id in: path description: Outgoing payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentDocument' required: true responses: '200': description: Outgoing payment updated content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Outgoing payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Outgoing Payments summary: Delete outgoing payment description: Deletes an outgoing payment. The `If-Match` header is accepted for API symmetry but not enforced (Cobro has no OPTLOCK). operationId: delete_32 parameters: - name: id in: path description: Outgoing payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' responses: '204': description: Outgoing payment deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Outgoing payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Outgoing Payments summary: Merge-patch outgoing payment description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_31 parameters: - name: id in: path description: Outgoing payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Outgoing payment patched content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Outgoing payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/origin-types/{id}: get: tags: - Origin Types summary: Get origin type by ID description: Returns a single claim origin type by its primary key. operationId: getById_32 parameters: - name: id in: path description: Origin type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Origin type found content: '*/*': schema: $ref: '#/components/schemas/OriginTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Origin type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Origin Types summary: Update origin type description: Full replacement of an existing claim origin type. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_32 parameters: - name: id in: path description: Origin type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/OriginTypeDocument' required: true responses: '200': description: Origin type updated content: '*/*': schema: $ref: '#/components/schemas/OriginTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Origin type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Origin Types summary: Delete origin type description: Deletes a claim origin type. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_33 parameters: - name: id in: path description: Origin type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Origin type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Origin type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Origin Types summary: Merge-patch origin type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_32 parameters: - name: id in: path description: Origin type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Origin type patched content: '*/*': schema: $ref: '#/components/schemas/OriginTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Origin type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/optical-orders/{id}: get: tags: - Optical Orders summary: Get optical order by ID description: Returns a single optical order with the full nested shape (per-eye prescription, treatments, colorations, supplements). operationId: getById_33 parameters: - name: id in: path description: Optical order ID required: true schema: type: integer format: int64 example: 123 responses: '200': description: Optical order found content: '*/*': schema: $ref: '#/components/schemas/OpticalOrderDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Optical order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Optical Orders summary: Update optical order description: Full replacement of an existing optical order. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_33 parameters: - name: id in: path description: Optical order ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/OpticalOrderDocument' required: true responses: '200': description: Optical order updated content: '*/*': schema: $ref: '#/components/schemas/OpticalOrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Optical order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Optical Orders summary: Delete optical order description: Deletes an optical order. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_34 parameters: - name: id in: path description: Optical order ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Optical order deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Optical order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Optical Orders summary: Merge-patch optical order description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_33 parameters: - name: id in: path description: Optical order ID required: true schema: type: integer format: int64 example: 123 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Optical order patched content: '*/*': schema: $ref: '#/components/schemas/OpticalOrderDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Optical order not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/notes/{id}: get: tags: - Notes summary: Get note by ID description: Returns a single note by its primary key. operationId: getById_34 parameters: - name: id in: path description: Note ID required: true schema: type: integer format: int64 example: 101 responses: '200': description: Note found content: '*/*': schema: $ref: '#/components/schemas/NoteDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing read permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Notes summary: Update note description: Full replacement of an existing note. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö Nota is not versioned). operationId: update_34 parameters: - name: id in: path description: Note ID required: true schema: type: integer format: int64 example: 101 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/NoteDocument' required: true responses: '200': description: Note updated content: '*/*': schema: $ref: '#/components/schemas/NoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing edit permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Notes summary: Delete note description: Deletes a note. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö Nota is not versioned). operationId: delete_35 parameters: - name: id in: path description: Note ID required: true schema: type: integer format: int64 example: 101 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Note deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing delete permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Notes summary: Merge-patch note description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_34 parameters: - name: id in: path description: Note ID required: true schema: type: integer format: int64 example: 101 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Note patched content: '*/*': schema: $ref: '#/components/schemas/NoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing edit permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Note not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/me/preferences: get: tags: - Preferences summary: Get my preferences description: Returns the authenticated user's preferences. Always allowed when the JWT is valid. operationId: getMyPreferences responses: '200': description: Preferences content: '*/*': schema: $ref: '#/components/schemas/UserPreferencesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Preferences summary: Update my preferences description: Updates the authenticated user's preferences. Null fields in the body are left untouched. operationId: updateMyPreferences requestBody: content: application/json: schema: $ref: '#/components/schemas/UserPreferencesDocument' required: true responses: '200': description: Preferences content: '*/*': schema: $ref: '#/components/schemas/UserPreferencesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets/{id}: get: tags: - Loyalty Wallets summary: Get loyalty wallet by ID description: Returns a single loyalty wallet by its primary key, including members and the current points balance. operationId: getById_35 parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Loyalty wallet found content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Loyalty Wallets summary: Update loyalty wallet description: >- Full replacement of an existing loyalty wallet. `members`: null leaves existing membership untouched; [] clears; non-empty list replaces. `counterpartyAccountId` only selects the owner among the supplied members (ignored if not listed). operationId: update_35 parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/LoyaltyWalletDocument' required: true responses: '200': description: Loyalty wallet updated content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Loyalty Wallets summary: Delete loyalty wallet description: Deletes a loyalty wallet. operationId: delete_36 parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Loyalty wallet deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Loyalty Wallets summary: Merge-patch loyalty wallet description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_35 parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Loyalty wallet patched content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-formats/{code}/favorite: put: tags: - Product Labels summary: Set label format favourite description: Marks or unmarks the label format as a favourite for the current user. operationId: setLabelFormatFavorite parameters: - name: code in: path description: Label format code required: true schema: type: string example: punched-3x8 requestBody: content: application/json: schema: $ref: '#/components/schemas/LabelFormatFavoriteRequest' required: true responses: '200': description: Updated label format content: '*/*': schema: $ref: '#/components/schemas/LabelFormatDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Label format not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/journal-entries/{id}: get: tags: - Journal Entries summary: Get journal entry by ID description: Returns a single journal entry including its lines. operationId: getById_36 parameters: - name: id in: path description: Journal entry ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Journal entry found content: '*/*': schema: $ref: '#/components/schemas/JournalEntryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Journal entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Journal Entries summary: Update journal entry description: Full replacement of an existing journal entry. operationId: update_36 parameters: - name: id in: path description: Journal entry ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/JournalEntryDocument' required: true responses: '200': description: Journal entry updated content: '*/*': schema: $ref: '#/components/schemas/JournalEntryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Journal entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Journal Entries summary: Delete journal entry description: Deletes a manual journal entry (`entryType=ASI`). System-generated entries must be removed from their source document. operationId: delete_37 parameters: - name: id in: path description: Journal entry ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Journal entry deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Journal entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Journal Entries summary: Merge-patch journal entry description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_36 parameters: - name: id in: path description: Journal entry ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Journal entry patched content: '*/*': schema: $ref: '#/components/schemas/JournalEntryDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Journal entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/item-types/{id}: get: tags: - Item Types summary: Get item type by ID description: Returns the item type including associatedAccounts. The response carries a strong `ETag` header (always `"0"` ÔÇö TipoArticulo is not versioned). operationId: getById_37 parameters: - name: id in: path description: Item type ID required: true schema: type: integer format: int64 example: 4 responses: '200': description: Item type found content: '*/*': schema: $ref: '#/components/schemas/ItemTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Item type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Item Types summary: Update item type description: Full replacement. On update, null associatedAccounts leaves existing children untouched; [] clears; non-empty list replaces. operationId: update_37 parameters: - name: id in: path description: Item type ID required: true schema: type: integer format: int64 example: 4 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ItemTypeDocument' required: true responses: '200': description: Item type updated content: '*/*': schema: $ref: '#/components/schemas/ItemTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Item type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Item Types summary: Delete item type description: Deletes the item type. If-Match is accepted but ignored (TipoArticulo is not versioned). operationId: delete_38 parameters: - name: id in: path description: Item type ID required: true schema: type: integer format: int64 example: 4 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Item type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Item type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Item Types summary: Merge-patch item type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_37 parameters: - name: id in: path description: Item type ID required: true schema: type: integer format: int64 example: 4 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Item type patched content: '*/*': schema: $ref: '#/components/schemas/ItemTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Item type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-counts/{id}: get: tags: - Inventory Counts summary: Get inventory count by ID description: >- Returns a single inventory count, including line detail (counted vs calculated quantities) and references to the generated stock adjustments when finalised. The response carries a strong `ETag` header with the current version. operationId: getById_38 parameters: - name: id in: path description: Inventory count ID required: true schema: type: integer format: int64 example: 501 responses: '200': description: Inventory count found content: '*/*': schema: $ref: '#/components/schemas/InventoryCountDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_INVENTARIOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory count not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Inventory Counts summary: Update inventory count (DRAFT only) description: >- Replaces the editable fields of a DRAFT inventory count. The `warehouseId` cannot be changed; if `lines` is supplied, the line set is fully replaced and the calculated quantities are recomputed against the current stock. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_38 parameters: - name: id in: path description: Inventory count ID required: true schema: type: integer format: int64 example: 501 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/InventoryCountDocument' required: true responses: '200': description: Inventory count updated content: '*/*': schema: $ref: '#/components/schemas/InventoryCountDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_INVENTARIOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory count not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. Also returned when the count is already FINALIZED. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Inventory Counts summary: Delete inventory count (DRAFT only) description: Deletes a DRAFT inventory count. A FINALIZED count cannot be deleted; create a compensating `inventory-entry`/`inventory-exit` instead. operationId: delete_39 parameters: - name: id in: path description: Inventory count ID required: true schema: type: integer format: int64 example: 501 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Inventory count deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_INVENTARIOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory count not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. Also returned when the count is already FINALIZED. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/incoming-payments/{id}: get: tags: - Incoming Payments summary: Get incoming payment by ID description: Returns a single incoming payment by its primary key. Returns 404 when the requested ID belongs to an outgoing payment. operationId: getById_39 parameters: - name: id in: path description: Incoming payment ID required: true schema: type: integer format: int64 example: 321 responses: '200': description: Incoming payment found content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Incoming payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Incoming Payments summary: Update incoming payment description: Full replacement of an existing incoming payment. The `If-Match` header is accepted for API symmetry but is not enforced (Cobro has no OPTLOCK). operationId: update_39 parameters: - name: id in: path description: Incoming payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentDocument' required: true responses: '200': description: Incoming payment updated content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Incoming payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Incoming Payments summary: Delete incoming payment description: Deletes an incoming payment. The `If-Match` header is accepted for API symmetry but not enforced (Cobro has no OPTLOCK). operationId: delete_40 parameters: - name: id in: path description: Incoming payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' responses: '204': description: Incoming payment deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Incoming payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Incoming Payments summary: Merge-patch incoming payment description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_38 parameters: - name: id in: path description: Incoming payment ID required: true schema: type: integer format: int64 example: 321 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. (accepted for symmetry; Cobro has no OPTLOCK) required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Incoming payment patched content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Incoming payment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/groups/{id}: get: tags: - Groups summary: Get group by ID description: Returns a single group by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_40 parameters: - name: id in: path description: Group ID required: true schema: type: integer format: int64 example: 7 responses: '200': description: Group found content: '*/*': schema: $ref: '#/components/schemas/GroupDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Groups summary: Update group description: Full replacement of an existing group. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_40 parameters: - name: id in: path description: Group ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/GroupDocument' required: true responses: '200': description: Group updated content: '*/*': schema: $ref: '#/components/schemas/GroupDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Groups summary: Delete group description: Deletes a group. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_41 parameters: - name: id in: path description: Group ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Group deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Groups summary: Merge-patch group description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_39 parameters: - name: id in: path description: Group ID required: true schema: type: integer format: int64 example: 7 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Group patched content: '*/*': schema: $ref: '#/components/schemas/GroupDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Group not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/equivalence-surcharge-types/{id}: get: tags: - Equivalence Surcharge Types summary: Get equivalence surcharge type by ID description: Returns the equivalence surcharge type including associatedAccounts. operationId: getById_41 parameters: - name: id in: path description: Equivalence surcharge type ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Equivalence surcharge type found content: '*/*': schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Equivalence surcharge type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Equivalence Surcharge Types summary: Update equivalence surcharge type description: Full replacement. On update, null associatedAccounts leaves existing children untouched; [] clears; non-empty list replaces. operationId: update_41 parameters: - name: id in: path description: Equivalence surcharge type ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' required: true responses: '200': description: Equivalence surcharge type updated content: '*/*': schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Equivalence surcharge type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Equivalence Surcharge Types summary: Delete equivalence surcharge type description: Deletes the equivalence surcharge type. If-Match is accepted but ignored (TipoRE is not versioned). operationId: delete_42 parameters: - name: id in: path description: Equivalence surcharge type ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Equivalence surcharge type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Equivalence surcharge type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Equivalence Surcharge Types summary: Merge-patch equivalence surcharge type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_40 parameters: - name: id in: path description: Equivalence surcharge type ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Equivalence surcharge type patched content: '*/*': schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Equivalence surcharge type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/employee-positions/{id}: get: tags: - Employee Positions summary: Get employee position by ID description: Returns a single employee store position by its primary key. operationId: getById_42 parameters: - name: id in: path description: Employee position ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Employee position found content: '*/*': schema: $ref: '#/components/schemas/EmployeePositionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Employee position not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Employee Positions summary: Update employee position description: Full replacement of an existing employee store position. operationId: update_42 parameters: - name: id in: path description: Employee position ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/EmployeePositionDocument' required: true responses: '200': description: Employee position updated content: '*/*': schema: $ref: '#/components/schemas/EmployeePositionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Employee position not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Employee Positions summary: Delete employee position description: Deletes an employee store position. operationId: delete_43 parameters: - name: id in: path description: Employee position ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Employee position deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Employee position not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Employee Positions summary: Merge-patch employee position description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_41 parameters: - name: id in: path description: Employee position ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Employee position patched content: '*/*': schema: $ref: '#/components/schemas/EmployeePositionDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Employee position not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/document-statuses/{id}: get: tags: - Document Statuses summary: Get document status by ID description: Returns a single custom document status by its primary key. operationId: getById_43 parameters: - name: id in: path description: Document status ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Document status found content: '*/*': schema: $ref: '#/components/schemas/DocumentStatusDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Document status not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Document Statuses summary: Update document status description: Full replacement of an existing custom document status. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_43 parameters: - name: id in: path description: Document status ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/DocumentStatusDocument' required: true responses: '200': description: Document status updated content: '*/*': schema: $ref: '#/components/schemas/DocumentStatusDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Document status not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Document Statuses summary: Delete document status description: Deletes a custom document status. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_44 parameters: - name: id in: path description: Document status ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Document status deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Document status not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Document Statuses summary: Merge-patch document status description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_42 parameters: - name: id in: path description: Document status ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Document status patched content: '*/*': schema: $ref: '#/components/schemas/DocumentStatusDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Document status not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/departments/{id}: get: tags: - Departments summary: Get department by ID description: Returns a single employee department by its primary key. operationId: getById_44 parameters: - name: id in: path description: Department ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Department found content: '*/*': schema: $ref: '#/components/schemas/DepartmentDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Department not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Departments summary: Update department description: Full replacement of an existing employee department. operationId: update_44 parameters: - name: id in: path description: Department ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/DepartmentDocument' required: true responses: '200': description: Department updated content: '*/*': schema: $ref: '#/components/schemas/DepartmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Department not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Departments summary: Delete department description: Deletes an employee department. operationId: delete_45 parameters: - name: id in: path description: Department ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Department deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Department not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Departments summary: Merge-patch department description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_43 parameters: - name: id in: path description: Department ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Department patched content: '*/*': schema: $ref: '#/components/schemas/DepartmentDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Department not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/customers/{id}: get: tags: - Customers summary: Get customer by ID description: Returns a single customer by its primary key. operationId: getById_45 parameters: - name: id in: path description: Customer ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Customer found content: '*/*': schema: $ref: '#/components/schemas/CustomerDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Customers summary: Update customer description: Full replacement of an existing customer. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_45 parameters: - name: id in: path description: Customer ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomerDocument' required: true responses: '200': description: Customer updated content: '*/*': schema: $ref: '#/components/schemas/CustomerDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Customers summary: Delete customer description: Deletes a customer. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_46 parameters: - name: id in: path description: Customer ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Customer deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Customers summary: Merge-patch customer description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_44 parameters: - name: id in: path description: Customer ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Customer patched content: '*/*': schema: $ref: '#/components/schemas/CustomerDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/customer-profiles/{id}: get: tags: - Customer Profiles summary: Get customer profile by ID description: Returns a single customer profile by its primary key. operationId: getById_46 parameters: - name: id in: path description: Customer profile ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Customer profile found content: '*/*': schema: $ref: '#/components/schemas/CustomerProfileDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer profile not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Customer Profiles summary: Update customer profile description: Full replacement of an existing customer profile. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_46 parameters: - name: id in: path description: Customer profile ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomerProfileDocument' required: true responses: '200': description: Customer profile updated content: '*/*': schema: $ref: '#/components/schemas/CustomerProfileDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer profile not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Customer Profiles summary: Delete customer profile description: Deletes a customer profile. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_47 parameters: - name: id in: path description: Customer profile ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Customer profile deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer profile not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Customer Profiles summary: Merge-patch customer profile description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_45 parameters: - name: id in: path description: Customer profile ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Customer profile patched content: '*/*': schema: $ref: '#/components/schemas/CustomerProfileDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Customer profile not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/custom-field-definitions/{id}: get: tags: - Custom Field Definitions summary: Get custom field definition by ID description: >- Returns a single definition by its primary key (enabled or not). The response carries a strong `ETag` header with the current version. For EAV-backed featureTypes (product-models, product-variants, manufacturing-custom-fields) the `featureType` query parameter is required to select the ges_customfield id namespace; no ETag is emitted for them. operationId: getById_47 parameters: - name: id in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models responses: '200': description: Custom field definition found content: '*/*': schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Custom Field Definitions summary: Update custom field definition description: >- Full replacement of an existing definition. `featureType` and `dataType` are immutable (stored values keyed by the id would stop matching); renaming `apiName`/`label` is always safe. `options` is rejected here: manage options through the `/options` sub-resource. Send the `If-Match` header with the current ETag for optimistic concurrency control. For EAV-backed featureTypes pass the `featureType` query parameter (If-Match is ignored for them). operationId: update_47 parameters: - name: id in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' required: true responses: '200': description: Custom field definition updated content: '*/*': schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Custom Field Definitions summary: Delete custom field definition description: >- Deletes a definition. Stored JSON values keyed by this id are left in place and ignored by readers (prefer disabling via `enabled=false` when the data should stay recoverable). Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_48 parameters: - name: id in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Custom field definition deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Custom Field Definitions summary: Merge-patch custom field definition description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_46 parameters: - name: id in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Custom field definition patched content: '*/*': schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/custom-field-definitions/{definitionId}/options/{optionId}: get: tags: - Custom Field Definitions summary: Get option by ID description: Returns a single option (enabled or not). The response carries a strong `ETag` header with the current version. operationId: getById_48 parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: optionId in: path description: Option ID required: true schema: type: integer format: int64 example: 31 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models responses: '200': description: Option found content: '*/*': schema: $ref: '#/components/schemas/CustomFieldOptionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Option not found for this definition content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Custom Field Definitions summary: Update option description: >- Full replacement (value, displayOrder, enabled). Renaming `value` does NOT rewrite previously stored entity values (they keep the old label and stop matching any option); prefer disabling the old option and creating a new one when the meaning changes. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_48 parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: optionId in: path description: Option ID required: true schema: type: integer format: int64 example: 31 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomFieldOptionDocument' required: true responses: '200': description: Option updated content: '*/*': schema: $ref: '#/components/schemas/CustomFieldOptionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Option not found for this definition content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Custom Field Definitions summary: Delete option description: >- Deletes an option. Previously stored entity values with this label are left in place (readable but no longer writable); prefer disabling via `enabled=false` when the data should stay consistent. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_49 parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: optionId in: path description: Option ID required: true schema: type: integer format: int64 example: 31 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Option deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Option not found for this definition content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/coupon-types/{id}: get: tags: - Coupon Types summary: Get coupon type by ID description: Returns a single coupon type by its primary key. operationId: getById_49 parameters: - name: id in: path description: Coupon type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Coupon type found content: '*/*': schema: $ref: '#/components/schemas/CouponTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Coupon type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Coupon Types summary: Update coupon type description: Full replacement of an existing coupon type. operationId: update_49 parameters: - name: id in: path description: Coupon type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CouponTypeDocument' required: true responses: '200': description: Coupon type updated content: '*/*': schema: $ref: '#/components/schemas/CouponTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Coupon type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Coupon Types summary: Delete coupon type description: Deletes a coupon type. operationId: delete_50 parameters: - name: id in: path description: Coupon type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Coupon type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Coupon type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Coupon Types summary: Merge-patch coupon type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_47 parameters: - name: id in: path description: Coupon type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Coupon type patched content: '*/*': schema: $ref: '#/components/schemas/CouponTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Coupon type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/verifactu-configuration: get: tags: - Verifactu Configuration summary: Get the company Verifactu configuration description: Returns the singleton configuration and its ETag. A company without a completed configuration returns 404. operationId: getVerifactuConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Configuration found content: '*/*': schema: $ref: '#/components/schemas/VerifactuConfigurationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing VER_CONFIGURACIONVERIFACTU permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside scope or configuration does not exist content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Verifactu Configuration summary: Upsert the company Verifactu configuration description: Atomically creates or replaces the singleton metadata. certificateId must reference a certificate uploaded for this company. operationId: upsertVerifactuConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/VerifactuConfigurationDocument' required: true responses: '200': description: Configuration created or updated content: '*/*': schema: $ref: '#/components/schemas/VerifactuConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONVERIFACTU permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/sat-mexico-configuration: get: tags: - SAT Mexico Configuration summary: Get the company Mexico SAT configuration description: Returns the singleton configuration and its ETag. A company without a completed configuration returns 404. operationId: getSatMexicoConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Configuration found content: '*/*': schema: $ref: '#/components/schemas/SatMexicoConfigurationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing VER_CONFIGURACIONSATMEXICO permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside scope or configuration does not exist content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - SAT Mexico Configuration summary: Upsert the company Mexico SAT configuration description: Atomically creates or replaces the singleton metadata. certificateId must reference a staged CSD (.cer + .key) uploaded for this company. operationId: upsertSatMexicoConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/SatMexicoConfigurationDocument' required: true responses: '200': description: Configuration created or updated content: '*/*': schema: $ref: '#/components/schemas/SatMexicoConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSATMEXICO permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/document-control-configuration: get: tags: - Document Control Configuration summary: Get the company document control configuration description: Returns the singleton configuration and its ETag. A company without a persisted configuration returns 404. operationId: getDocumentControlConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Configuration found content: '*/*': schema: $ref: '#/components/schemas/DocumentControlConfigurationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_EMPRESAS permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside scope or configuration does not exist content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Document Control Configuration summary: Upsert the company document control configuration description: >- Creates or partially updates the singleton configuration. Omitted or null scalar fields are left unchanged. Category lists omitted or null are left unchanged; send an empty array to clear a list. When a payment-control flag is true, the corresponding minimum charged percentage must be present in the final stored state. Category IDs must belong to companyId. Use If-Match with the ETag from GET for optimistic locking on updates. operationId: upsertDocumentControlConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/DocumentControlConfigurationDocument' required: true responses: '200': description: Configuration created or updated content: '*/*': schema: $ref: '#/components/schemas/DocumentControlConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_EMPRESAS permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/chile-sii-configuration: get: tags: - Chile SII Configuration summary: Get the company Chile SII configuration description: Returns the singleton configuration and its ETag. A company without a completed configuration returns 404. operationId: getChileSiiConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Configuration found content: '*/*': schema: $ref: '#/components/schemas/ChileSiiConfigurationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing VER_CONFIGURACIONSIICHILE permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside scope or configuration does not exist content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Chile SII Configuration summary: Upsert the company Chile SII configuration description: Atomically creates or replaces the singleton metadata. certificateId must reference a certificate uploaded for this company. operationId: upsertChileSiiConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ChileSiiConfigurationDocument' required: true responses: '200': description: Configuration created or updated content: '*/*': schema: $ref: '#/components/schemas/ChileSiiConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSIICHILE permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/collections/{id}: get: tags: - Collections summary: Get collection by ID description: Returns a single collection by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_50 parameters: - name: id in: path description: Collection ID required: true schema: type: integer format: int64 example: 3 responses: '200': description: Collection found content: '*/*': schema: $ref: '#/components/schemas/CollectionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Collection not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Collections summary: Update collection description: Full replacement of an existing collection. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_50 parameters: - name: id in: path description: Collection ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CollectionDocument' required: true responses: '200': description: Collection updated content: '*/*': schema: $ref: '#/components/schemas/CollectionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Collection not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Collections summary: Delete collection description: Deletes a collection. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_51 parameters: - name: id in: path description: Collection ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Collection deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Collection not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Collections summary: Merge-patch collection description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_48 parameters: - name: id in: path description: Collection ID required: true schema: type: integer format: int64 example: 3 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Collection patched content: '*/*': schema: $ref: '#/components/schemas/CollectionDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Collection not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-types/{id}: get: tags: - Claim Types summary: Get claim type by ID description: Returns a single claim type by its primary key, including configured solutions. operationId: getById_51 parameters: - name: id in: path description: Claim type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Claim type found content: '*/*': schema: $ref: '#/components/schemas/ClaimTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Claim Types summary: Update claim type description: Full replacement of an existing claim type and its configured solutions. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_51 parameters: - name: id in: path description: Claim type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ClaimTypeDocument' required: true responses: '200': description: Claim type updated content: '*/*': schema: $ref: '#/components/schemas/ClaimTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Claim Types summary: Delete claim type description: Deletes a claim type. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_52 parameters: - name: id in: path description: Claim type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Claim type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Claim Types summary: Merge-patch claim type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_49 parameters: - name: id in: path description: Claim type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Claim type patched content: '*/*': schema: $ref: '#/components/schemas/ClaimTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-causes/{id}: get: tags: - Claim Causes summary: Get claim cause by ID description: Returns a single claim cause by its primary key. operationId: getById_52 parameters: - name: id in: path description: Claim cause ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Claim cause found content: '*/*': schema: $ref: '#/components/schemas/ClaimCauseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Claim Causes summary: Update claim cause description: Full replacement of an existing claim cause. Send the `If-Match` header for optimistic concurrency (accepted but ignored ├óÔé¼ÔÇØ not versioned). operationId: update_52 parameters: - name: id in: path description: Claim cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ClaimCauseDocument' required: true responses: '200': description: Claim cause updated content: '*/*': schema: $ref: '#/components/schemas/ClaimCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Claim Causes summary: Delete claim cause description: Deletes a claim cause. Send the `If-Match` header with the current ETag (accepted but ignored ├óÔé¼ÔÇØ not versioned). operationId: delete_53 parameters: - name: id in: path description: Claim cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Claim cause deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Claim Causes summary: Merge-patch claim cause description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_50 parameters: - name: id in: path description: Claim cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Claim cause patched content: '*/*': schema: $ref: '#/components/schemas/ClaimCauseDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Claim cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/categories/{id}: get: tags: - Categories summary: Get category by ID description: Returns a single category by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_53 parameters: - name: id in: path description: Category ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Category found content: '*/*': schema: $ref: '#/components/schemas/CategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Category not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Categories summary: Update category description: Full replacement of an existing category. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_53 parameters: - name: id in: path description: Category ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CategoryDocument' required: true responses: '200': description: Category updated content: '*/*': schema: $ref: '#/components/schemas/CategoryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Category not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Categories summary: Delete category description: Deletes a category. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_54 parameters: - name: id in: path description: Category ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Category deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Category not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Categories summary: Merge-patch category description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_51 parameters: - name: id in: path description: Category ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Category patched content: '*/*': schema: $ref: '#/components/schemas/CategoryDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Category not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes/{id}: get: tags: - Cash Closes summary: Get cash close by ID description: Returns a single cash close including payment-method lines and optional cash withdrawals. operationId: getById_54 parameters: - name: id in: path description: Cash close ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Cash close found content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Cash Closes summary: Update cash close description: Full replacement of an existing cash close. `warehouseId` is immutable. When balances change, the legacy facade propagates subsequent closes via `updateNextSaldosCaja`. operationId: update_54 parameters: - name: id in: path description: Cash close ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CashCloseDocument' required: true responses: '200': description: Cash close updated content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Cash Closes summary: Delete cash close description: Deletes a cash close. Closed registers with withdrawals are re-opened in the legacy flow before deletion. operationId: delete_55 parameters: - name: id in: path description: Cash close ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Cash close deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Cash Closes summary: Merge-patch cash close description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_52 parameters: - name: id in: path description: Cash close ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Cash close patched content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/card-types/{id}: get: tags: - Card Types summary: Get card type by ID description: Returns a single card type by its primary key. operationId: getById_55 parameters: - name: id in: path description: Card type ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Card type found content: '*/*': schema: $ref: '#/components/schemas/CardTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Card type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Card Types summary: Update card type description: Full replacement of an existing card type. operationId: update_55 parameters: - name: id in: path description: Card type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CardTypeDocument' required: true responses: '200': description: Card type updated content: '*/*': schema: $ref: '#/components/schemas/CardTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Card type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Card Types summary: Delete card type description: Deletes a card type. operationId: delete_56 parameters: - name: id in: path description: Card type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Card type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Card type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Card Types summary: Merge-patch card type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_53 parameters: - name: id in: path description: Card type ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Card type patched content: '*/*': schema: $ref: '#/components/schemas/CardTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Card type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cancellation-causes/{id}: get: tags: - Cancellation Causes summary: Get cancellation cause by ID description: Returns a single cancellation cause by its primary key. operationId: getById_56 parameters: - name: id in: path description: Cancellation cause ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Cancellation cause found content: '*/*': schema: $ref: '#/components/schemas/CancellationCauseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cancellation cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Cancellation Causes summary: Update cancellation cause description: Full replacement of an existing cancellation cause. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_56 parameters: - name: id in: path description: Cancellation cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CancellationCauseDocument' required: true responses: '200': description: Cancellation cause updated content: '*/*': schema: $ref: '#/components/schemas/CancellationCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cancellation cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Cancellation Causes summary: Delete cancellation cause description: Deletes a cancellation cause. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_57 parameters: - name: id in: path description: Cancellation cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Cancellation cause deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cancellation cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Cancellation Causes summary: Merge-patch cancellation cause description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_54 parameters: - name: id in: path description: Cancellation cause ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Cancellation cause patched content: '*/*': schema: $ref: '#/components/schemas/CancellationCauseDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cancellation cause not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/campaigns/{id}: get: tags: - Campaigns summary: Get campaign by ID description: Returns a single campaign by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_57 parameters: - name: id in: path description: Campaign ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Campaign found content: '*/*': schema: $ref: '#/components/schemas/CampaignDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Campaign not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Campaigns summary: Update campaign description: Full replacement of an existing campaign. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_57 parameters: - name: id in: path description: Campaign ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CampaignDocument' required: true responses: '200': description: Campaign updated content: '*/*': schema: $ref: '#/components/schemas/CampaignDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Campaign not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Campaigns summary: Delete campaign description: Deletes a campaign. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_58 parameters: - name: id in: path description: Campaign ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Campaign deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Campaign not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Campaigns summary: Merge-patch campaign description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_55 parameters: - name: id in: path description: Campaign ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Campaign patched content: '*/*': schema: $ref: '#/components/schemas/CampaignDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Campaign not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/calendars/{id}: get: tags: - Calendars summary: Get calendar by ID description: Returns a single calendar by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_58 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 responses: '200': description: Calendar found content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Calendars summary: Update calendar description: Full replacement of an existing calendar. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_58 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarDocument' required: true responses: '200': description: Calendar updated content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Calendars summary: Delete calendar description: Deletes a calendar. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_59 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Calendar deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Calendars summary: Merge-patch calendar description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_56 parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Calendar patched content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/brands/{id}: get: tags: - Brands summary: Get brand by ID description: Returns a single brand by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_59 parameters: - name: id in: path description: Brand ID required: true schema: type: integer format: int64 example: 10 responses: '200': description: Brand found content: '*/*': schema: $ref: '#/components/schemas/BrandDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Brand not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Brands summary: Update brand description: Full replacement of an existing brand. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_59 parameters: - name: id in: path description: Brand ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/BrandDocument' required: true responses: '200': description: Brand updated content: '*/*': schema: $ref: '#/components/schemas/BrandDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Brand not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Brands summary: Delete brand description: Deletes a brand. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_60 parameters: - name: id in: path description: Brand ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Brand deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Brand not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Brands summary: Merge-patch brand description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_57 parameters: - name: id in: path description: Brand ID required: true schema: type: integer format: int64 example: 10 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Brand patched content: '*/*': schema: $ref: '#/components/schemas/BrandDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Brand not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/associated-contact-types/{id}: get: tags: - Associated Contact Types summary: Get associated contact type by ID description: Returns a single associated contact type by its primary key. operationId: getById_60 parameters: - name: id in: path description: Associated contact type ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Associated contact type found content: '*/*': schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Associated contact type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Associated Contact Types summary: Update associated contact type description: Full replacement of an existing associated contact type. Send the `If-Match` header for optimistic concurrency (accepted but ignored ÔÇö not versioned). operationId: update_60 parameters: - name: id in: path description: Associated contact type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' required: true responses: '200': description: Associated contact type updated content: '*/*': schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Associated contact type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Associated Contact Types summary: Delete associated contact type description: Deletes an associated contact type. Send the `If-Match` header with the current ETag (accepted but ignored ÔÇö not versioned). operationId: delete_61 parameters: - name: id in: path description: Associated contact type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Associated contact type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Associated contact type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Associated Contact Types summary: Merge-patch associated contact type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_58 parameters: - name: id in: path description: Associated contact type ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Associated contact type patched content: '*/*': schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Associated contact type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointments/{id}: get: tags: - Appointments summary: Get appointment by ID description: Returns a single appointment / calendar event by its primary key. operationId: getById_61 parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 responses: '200': description: Appointment found content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Appointments summary: Update appointment description: Full replacement of an existing appointment. Evento has no `OPTLOCK` column, so `If-Match` is accepted for API symmetry but ignored by the command gateway. operationId: update_61 parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 - name: If-Match in: header description: Accepted for API symmetry; ignored because Evento has no OPTLOCK column. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentDocument' required: true responses: '200': description: Appointment updated content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Appointments summary: Delete appointment description: Deletes an appointment. Evento has no `OPTLOCK` column, so `If-Match` is accepted for API symmetry but ignored. operationId: delete_62 parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 - name: If-Match in: header description: Accepted for API symmetry; ignored because Evento has no OPTLOCK column. required: false schema: type: string example: '3' responses: '204': description: Appointment deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Appointments summary: Merge-patch appointment description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. Evento has no `OPTLOCK` column, so `If-Match` is accepted for API symmetry but ignored by the command gateway. operationId: patch_59 parameters: - name: id in: path description: Appointment ID required: true schema: type: integer format: int64 example: 1001 - name: If-Match in: header description: Accepted for API symmetry; ignored because Evento has no OPTLOCK column. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Appointment patched content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointment-types/{id}: get: tags: - Appointment Types summary: Get appointment type by ID description: Returns a single appointment type by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_62 parameters: - name: id in: path description: Appointment type ID required: true schema: type: integer format: int64 example: 12 responses: '200': description: Appointment type found content: '*/*': schema: $ref: '#/components/schemas/AppointmentTypeDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Appointment Types summary: Update appointment type description: Full replacement of an existing appointment type. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_62 parameters: - name: id in: path description: Appointment type ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentTypeDocument' required: true responses: '200': description: Appointment type updated content: '*/*': schema: $ref: '#/components/schemas/AppointmentTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Appointment Types summary: Delete appointment type description: Deletes an appointment type. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_63 parameters: - name: id in: path description: Appointment type ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Appointment type deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Appointment Types summary: Merge-patch appointment type description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_60 parameters: - name: id in: path description: Appointment type ID required: true schema: type: integer format: int64 example: 12 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Appointment type patched content: '*/*': schema: $ref: '#/components/schemas/AppointmentTypeDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment type not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointment-services/{id}: get: tags: - Appointment Services summary: Get appointment service by ID description: Returns a single appointment service by its primary key. The response carries a strong `ETag` header with the current version. operationId: getById_63 parameters: - name: id in: path description: Appointment service ID required: true schema: type: integer format: int64 example: 55 responses: '200': description: Appointment service found content: '*/*': schema: $ref: '#/components/schemas/AppointmentServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment service not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Appointment Services summary: Update appointment service description: Full replacement of an existing appointment service. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: update_63 parameters: - name: id in: path description: Appointment service ID required: true schema: type: integer format: int64 example: 55 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentServiceDocument' required: true responses: '200': description: Appointment service updated content: '*/*': schema: $ref: '#/components/schemas/AppointmentServiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment service not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Appointment Services summary: Delete appointment service description: Deletes an appointment service. Send the `If-Match` header with the current ETag for optimistic concurrency control. operationId: delete_64 parameters: - name: id in: path description: Appointment service ID required: true schema: type: integer format: int64 example: 55 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Appointment service deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment service not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Appointment Services summary: Merge-patch appointment service description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_61 parameters: - name: id in: path description: Appointment service ID required: true schema: type: integer format: int64 example: 55 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Appointment service patched content: '*/*': schema: $ref: '#/components/schemas/AppointmentServiceDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment service not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Version conflict ÔÇö the resource was modified by another user since the version supplied in `If-Match` was issued. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/activities/{id}: get: tags: - Activities summary: Get activity by ID description: Returns a single accounting activity by its primary key. operationId: getById_64 parameters: - name: id in: path description: Activity ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Activity found content: '*/*': schema: $ref: '#/components/schemas/ActivityDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Activity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Activities summary: Update activity description: Full replacement of an existing accounting activity. operationId: update_64 parameters: - name: id in: path description: Activity ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/ActivityDocument' required: true responses: '200': description: Activity updated content: '*/*': schema: $ref: '#/components/schemas/ActivityDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Activity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Activities summary: Delete activity description: Deletes an accounting activity. operationId: delete_65 parameters: - name: id in: path description: Activity ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Activity deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Activity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Activities summary: Merge-patch activity description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_62 parameters: - name: id in: path description: Activity ID required: true schema: type: integer format: int64 example: 5 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Activity patched content: '*/*': schema: $ref: '#/components/schemas/ActivityDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Activity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/accounting-accounts/{id}: get: tags: - Accounting Accounts summary: Get accounting account by ID description: Returns a single chart-of-accounts entry. operationId: getById_65 parameters: - name: id in: path description: Accounting account ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Accounting account found content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Accounting account not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' put: tags: - Accounting Accounts summary: Update accounting account description: Full replacement. The account number must keep the company's configured length. operationId: update_65 parameters: - name: id in: path description: Accounting account ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/json: schema: $ref: '#/components/schemas/AccountingAccountDocument' required: true responses: '200': description: Accounting account updated content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Accounting account not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Accounting Accounts summary: Delete accounting account description: Deletes a sub-account. Rollup (parent) accounts cannot be deleted. If-Match is accepted but ignored (CuentaContable is not versioned). operationId: delete_66 parameters: - name: id in: path description: Accounting account ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '204': description: Accounting account deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Accounting account not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Accounting Accounts summary: Merge-patch accounting account description: >- RFC 7396 merge-patch over `application/merge-patch+json`. Send only the fields you want to change; include a field with value `null` to remove it. Use the `If-Match` header for optimistic concurrency control. operationId: patch_63 parameters: - name: id in: path description: Accounting account ID required: true schema: type: integer format: int64 example: 42 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Accounting account patched content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned for malformed merge-patch payloads. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Accounting account not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/warehouse-types: get: tags: - Warehouse Types summary: List warehouse types description: >- Returns a paginated list of warehouse types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of warehouse types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Warehouse Types summary: Create warehouse type description: Creates a new warehouse type. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create requestBody: content: application/json: schema: $ref: '#/components/schemas/WarehouseTypeDocument' required: true responses: '201': description: Warehouse type created content: '*/*': schema: $ref: '#/components/schemas/WarehouseTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Warehouse Types summary: Bulk delete warehouse types description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteWarehouseTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/warehouse-types/new: post: tags: - Warehouse Types summary: Prototype warehouse type for a creation form description: >- Returns a non-persisted warehouse type pre-populated with backend defaults (`enabled=true`, current company, next sequential `code`, empty `name`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/warehouse-types` afterwards to persist. operationId: prepareCreateWarehouseType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Warehouse type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/WarehouseTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIENDATIPOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visual-therapy-templates: get: tags: - Visual Therapy Templates summary: List visual therapy templates description: >- Returns a paginated list of visual therapy exercise templates with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_1 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of visual therapy templates content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Visual Therapy Templates summary: Create visual therapy template description: Creates a new visual therapy exercise template. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_1 requestBody: content: application/json: schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' required: true responses: '201': description: Visual therapy template created content: '*/*': schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visual-therapy-templates/new: post: tags: - Visual Therapy Templates summary: Prototype visual therapy template for a creation form description: >- Returns a non-persisted visual therapy exercise template pre-populated with backend defaults (`enabled=true`, current company and branch when available). Optional JSON hints: `companyId`, `warehouseId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/visual-therapy-templates` afterwards to persist. operationId: prepareCreateVisualTherapyTemplate requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Visual therapy template prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/VisualTherapyTemplateDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PLANTILLA_EJER_TERAPIA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visit-reasons: get: tags: - Visit Reasons summary: List visit reasons description: >- Returns a paginated list of visit reasons with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_2 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of visit reasons content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Visit Reasons summary: Create visit reason description: >- Creates a new visit reason. Business logic runs in the legacy WAR. `code` is optional: when omitted the WAR assigns the next sequential company-scoped code (same rule as `POST /visit-reasons/new`). operationId: create_2 requestBody: content: application/json: schema: $ref: '#/components/schemas/VisitReasonDocument' required: true responses: '201': description: Visit reason created content: '*/*': schema: $ref: '#/components/schemas/VisitReasonDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Visit Reasons summary: Bulk delete visit reasons description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteVisitReasons requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Visit Reasons summary: Bulk patch visit reasons description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `enabled`, `description`.' operationId: bulkPatchVisitReasons requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/visit-reasons/new: post: tags: - Visit Reasons summary: Prototype visit reason for a creation form description: >- Returns a non-persisted visit reason pre-populated with backend defaults (current company, next sequential `code`, `enabled=true`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/visit-reasons` to persist. operationId: prepareCreateVisitReason requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Visit reason prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/VisitReasonDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MOTIVOSDEVISITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views: get: tags: - Views summary: List view templates for a feature description: >- Returns every template the caller can use for the given featureType: the system view (`{featureType}-main`, always first, not editable), then the tenant-shared templates (`visibility=everyone`) and the caller's private ones, each bucket sorted alphabetically. `canEdit`/`canDelete` are computed for the caller: owner of the template, or holder of the EDITAR_PLANTILLASGLOBALES permission. operationId: list_3 parameters: - name: featureType in: query description: Registered featureType of the listing required: true schema: type: string example: brands responses: '200': description: Templates visible to the caller content: '*/*': schema: type: array items: $ref: '#/components/schemas/ViewTemplateSummary' '400': description: Missing or unknown featureType content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the entity's read permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Views summary: Create a named view template description: >- Creates a template from the grid's current column state. `columns` follows the same shape and normalization as saveViewLayout (order + width; PK, FK pairs and ALWAYS_VISIBLE_COLUMN fields are added by the backend on the next GET). The name is unique (case-insensitive) per (tenant, featureType, owner). Creating with `visibility=everyone` requires the EDITAR_PLANTILLASGLOBALES permission. The create does NOT change the caller's selected template; that stays in `PUT /api/v2/me/preferences` (viewTemplates). operationId: create_3 requestBody: content: application/json: schema: $ref: '#/components/schemas/ViewTemplateCreateRequest' required: true responses: '201': description: Template created content: '*/*': schema: $ref: '#/components/schemas/ViewTemplateSummary' '400': description: Invalid name, unknown featureType, empty columns or unknown apiNames content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing read permission, or visibility=everyone without EDITAR_PLANTILLASGLOBALES content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: A template with the same name already exists for this feature and owner content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/{viewId}/data: post: tags: - Views summary: Fetch rows for a grid view description: >- Returns a page of rows that satisfies the QueryDSL (pagination, sort, filter, search, grouping, drill-down). Order of evaluation: search → filter → sort → pagination. The hard limit is 500 rows per page. operationId: getViewData parameters: - name: viewId in: path description: Registered view identifier required: true schema: type: string example: brands-main requestBody: content: application/json: schema: $ref: '#/components/schemas/QueryDsl' responses: '200': description: Page of rows for the requested view content: '*/*': schema: $ref: '#/components/schemas/ViewDataResponse' '400': description: Invalid QueryDSL (unknown field, incompatible operator, limit > 500, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the entity's read permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/users-main/data: post: tags: - Users summary: users-main SSRM data operationId: data requestBody: content: application/json: schema: $ref: '#/components/schemas/QueryDsl' responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/vat-types: get: tags: - Vat Types summary: List VAT types description: Paginated list with optional RSQL filter and sort (default lastModifiedAt:desc). Child collections are omitted; use GET /{id} for warehouseOverrides and associatedAccounts. operationId: list_4 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*21* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-12-31T23:59:59Z' responses: '200': description: Page of VAT types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Vat Types summary: Create VAT type description: 'Persists via the internal commands gateway. warehouseOverrides/associatedAccounts: null leaves empty; [] clears; list replaces.' operationId: create_4 requestBody: content: application/json: schema: $ref: '#/components/schemas/VatTypeDocument' required: true responses: '201': description: VAT type created content: '*/*': schema: $ref: '#/components/schemas/VatTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/vat-types/new: post: tags: - Vat Types summary: Prototype a VAT type for a creation form description: 'Non-persisted defaults: current company, enabled=true, blockType=null. Optional JSON hints: companyId, surchargeTypeId, copyFromId.' operationId: prepareCreateVatType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: VAT type prototype content: '*/*': schema: $ref: '#/components/schemas/VatTypeDocument' '400': description: Hint references an unknown entity content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSIVA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/sessions/{familyId}/close: post: tags: - Users summary: Close a session operationId: closeSession parameters: - name: id in: path required: true schema: type: integer format: int64 - name: familyId in: path required: true schema: type: string responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/sessions/close-all: post: tags: - Users summary: Close all sessions operationId: closeAllSessions parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions/save-as-role: post: tags: - Users summary: Save the customized permission set as a new ERP role and assign it description: Creates a core_role from the user's private permission copy (name must be unique in the tenant) and assigns it to the user. operationId: savePermissionsAsRole parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/json: schema: $ref: '#/components/schemas/SaveAsRoleRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/password/reset: post: tags: - Users summary: Reset password (force change on next login) operationId: resetPassword parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/password/force-change: post: tags: - Users summary: Force password change on next login operationId: forcePasswordChange parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/ip-restrictions/ips: post: tags: - Users summary: Authorize an IP operationId: addAuthorizedIp parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthorizedIpRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/user-invitations: get: tags: - User Invitations summary: List pending invitations operationId: pending responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - User Invitations summary: Invite a user operationId: invite requestBody: content: application/json: schema: $ref: '#/components/schemas/InviteUserRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/user-invitations/{id}/resend: post: tags: - User Invitations summary: Resend a pending invitation operationId: resend parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solutions: get: tags: - Solutions summary: List solutions description: >- Returns a paginated list of claim solution configurations with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `title:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_5 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: title:asc example: title:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of solutions content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Solutions summary: Create solution description: Creates a new claim solution configuration. Business logic runs in the legacy WAR via the internal commands gateway. Requires `claimTypeId` and `solutionTypeId`. operationId: create_5 requestBody: content: application/json: schema: $ref: '#/components/schemas/SolutionDocument' required: true responses: '201': description: Solution created content: '*/*': schema: $ref: '#/components/schemas/SolutionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solutions/new: post: tags: - Solutions summary: Prototype solution for a creation form description: >- Returns a non-persisted claim solution pre-populated with backend defaults (`enabled=true`, parent claim type company). Optional JSON hints: `claimTypeId` (required), `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/solutions` afterwards to persist. operationId: prepareCreateSolution requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Solution prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/SolutionDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solution-types: get: tags: - Solution Types summary: List solution types description: >- Returns a paginated list of claim solution types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_6 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of solution types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Solution Types summary: Create solution type description: Creates a new claim solution type. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_6 requestBody: content: application/json: schema: $ref: '#/components/schemas/SolutionTypeDocument' required: true responses: '201': description: Solution type created content: '*/*': schema: $ref: '#/components/schemas/SolutionTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/solution-types/new: post: tags: - Solution Types summary: Prototype solution type for a creation form description: >- Returns a non-persisted claim solution type pre-populated with backend defaults (`enabled=true`, next `code`, current company). Optional JSON hints: `companyId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/solution-types` afterwards to persist. operationId: prepareCreateSolutionType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Solution type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/SolutionTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPOSOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/series: get: tags: - Series summary: List series description: >- Returns a paginated list of numbering series with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `series:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_7 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: documentKind==FAC-EMI - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: series:asc example: series:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of series content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Series summary: Create series description: Creates a new numbering series. Business logic runs in the legacy WAR via the internal commands gateway. The combination `series` + `documentKind` + `companyId` must be unique. operationId: create_7 requestBody: content: application/json: schema: $ref: '#/components/schemas/SeriesDocument' required: true responses: '201': description: Series created content: '*/*': schema: $ref: '#/components/schemas/SeriesDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/series/new: post: tags: - Series summary: Prototype series for a creation form description: >- Returns a non-persisted series pre-populated with backend defaults (`enabled=true`, current company). Optional JSON hints: `companyId`, `documentKind` (e.g. FAC-EMI), `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/series` afterwards to persist. operationId: prepareCreateSeries requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Series prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/SeriesDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_SERIES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/locations: get: tags: - Service Locations summary: List service locations operationId: list_8 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/PageResponseServiceLocationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Service Locations summary: Create service location operationId: create_8 requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceLocationDocument' required: true responses: '201': description: Created content: '*/*': schema: $ref: '#/components/schemas/ServiceLocationDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/categories: get: tags: - Service Categories summary: List service categories operationId: list_9 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: sortOrder:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/PageResponseServiceCategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Service Categories summary: Create service category operationId: create_9 requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceCategoryDocument' required: true responses: '201': description: Created content: '*/*': schema: $ref: '#/components/schemas/ServiceCategoryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/catalog: get: tags: - Service Catalog summary: List service catalog operationId: list_10 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/PageResponseServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Service Catalog summary: Create service operationId: create_10 requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceDocument' required: true responses: '201': description: Created content: '*/*': schema: $ref: '#/components/schemas/ServiceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/services/bookings: get: tags: - Service Bookings summary: List service bookings operationId: list_11 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: startTime:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 responses: '200': description: OK content: '*/*': schema: $ref: '#/components/schemas/PageResponseServiceBookingDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Service Bookings summary: Create service booking operationId: create_11 parameters: - name: overrideAvailability in: query required: false schema: type: boolean default: false - name: skipSchedulingNotice in: query required: false schema: type: boolean default: false requestBody: content: application/json: schema: $ref: '#/components/schemas/ServiceBookingDocument' required: true responses: '201': description: Created content: '*/*': schema: $ref: '#/components/schemas/ServiceBookingDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/events: post: tags: - Scheduling Events summary: Book an appointment description: >- Creates an appointment after checking the requested interval against the availability engine. The check and the insert share one transaction and one pessimistic lock over the calendar's and the assignee's agenda, so a second booking of the same slot waits and is then rejected. operationId: createSchedulingEvent parameters: - name: ignoreDateRange in: query description: >- Skips the calendar's booking window ÔÇö the minimum scheduling notice (`allowBookingAfter`) and the horizon (`allowBookingFor`). Every other availability rule still applies. Equivalent to GHL `ignoreDateRange`. Recorded on the appointment's `bookingLog`. required: false schema: type: boolean default: false example: false - name: ignoreFreeSlotValidation in: query description: >- Skips the availability check entirely, letting the counter overbook on purpose. The agenda is still locked, so concurrent writes stay serialised. Equivalent to GHL `ignoreFreeSlotValidation`. Recorded on the appointment's `bookingLog`. required: false schema: type: boolean default: false example: false requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentDocument' required: true responses: '201': description: Appointment booked content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar, branch or related entity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: The payload is valid but the engine does not offer that interval. The `detail` names the slots that were available that day. Retry with `ignoreFreeSlotValidation=true` to book it anyway. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/events/block-slots: get: tags: - Block Slots summary: List block slots description: Returns a paginated list of block slots with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `startAt:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_12 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: calendarId==2;startAt=ge=2026-07-01T00:00:00Z - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: startAt:asc example: startAt:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of block slots content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Block Slots summary: Create block slot description: >- Creates a block. Exactly one of `calendarId` / `employeeId` must be set; supplying both or neither returns 400. The owning company is derived from the target and must be inside the caller's scope. operationId: create_12 requestBody: content: application/json: schema: $ref: '#/components/schemas/BlockSlotDocument' required: true responses: '201': description: Block slot created content: '*/*': schema: $ref: '#/components/schemas/BlockSlotDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Also returned when both or neither of calendarId / employeeId are set. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CALENDARIOBLOQUEOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Target calendar or employee not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars: get: tags: - Scheduling Calendars summary: List calendars description: Returns a paginated list of calendars with the full GHL-like contract. Envelope `{data, totalCount, skip, limit, hasMore}`. Default sort `name:asc`. Limit capped at 200. operationId: list_13 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: calendarType==branch - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of calendars content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Scheduling Calendars summary: Create calendar description: Creates a calendar with GHL-like validation (personal/collective/branch teamMember rules). Persisted via the WAR command gateway so CalendarioListener fires. operationId: create_13 requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarDocument' required: true responses: '201': description: Calendar created content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/schedules: get: tags: - Staff Schedules summary: List staff schedules operationId: list_14 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: active==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of staff schedules content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Staff Schedules summary: Create staff schedule operationId: create_14 requestBody: content: application/json: schema: $ref: '#/components/schemas/StaffScheduleDocument' required: true responses: '201': description: Staff schedule created content: '*/*': schema: $ref: '#/components/schemas/StaffScheduleDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_HORARIOSTRABAJADOR` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/resources/rooms: get: tags: - Calendar Rooms summary: List calendar rooms operationId: list_15 parameters: - name: filter in: query required: false schema: type: string - name: sort in: query required: false schema: type: string default: name:asc - name: skip in: query required: false schema: type: integer format: int32 default: 0 - name: limit in: query required: false schema: type: integer format: int32 default: 50 responses: '200': description: Page of calendar rooms content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIORECURSOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Calendar Rooms summary: Create calendar room operationId: create_15 requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarResourceDocument' required: true responses: '201': description: Calendar room created content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/resources/equipments: get: tags: - Calendar Equipments summary: List calendar equipments operationId: list_16 parameters: - name: filter in: query required: false schema: type: string - name: sort in: query required: false schema: type: string default: name:asc - name: skip in: query required: false schema: type: integer format: int32 default: 0 - name: limit in: query required: false schema: type: integer format: int32 default: 50 responses: '200': description: Page of calendar equipments content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIORECURSOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Calendar Equipments summary: Create calendar equipment operationId: create_16 requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarResourceDocument' required: true responses: '201': description: Calendar equipment created content: '*/*': schema: $ref: '#/components/schemas/CalendarResourceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/groups: get: tags: - Calendar Groups summary: List calendar groups description: Returns a paginated list of calendar groups with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_17 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: active==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of calendar groups content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Calendar Groups summary: Create calendar group operationId: create_17 requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarGroupDocument' required: true responses: '201': description: Calendar group created content: '*/*': schema: $ref: '#/components/schemas/CalendarGroupDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CALENDARIOGRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/appointments/{appointmentId}/notes: get: tags: - Appointment Notes summary: List appointment notes description: >- Returns a paginated list of the notes of one appointment, with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `createdAt:desc`. Limit is capped at 200; skip is clamped to >= 0. operationId: listAppointmentNotes parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: employeeId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: createdAt:desc example: createdAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of notes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Appointment Notes summary: Create appointment note description: Adds a note to an appointment. The owning appointment comes from the path; `appointmentId` in the body is ignored. operationId: createAppointmentNote parameters: - name: appointmentId in: path description: Owning appointment ID required: true schema: type: integer format: int64 example: 1001 requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentNoteDocument' required: true responses: '201': description: Note created content: '*/*': schema: $ref: '#/components/schemas/AppointmentNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Appointment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-quotes: get: tags: - Sales Quotes summary: List sales quotes description: >- Returns a paginated list of customer sales quotes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_18 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: issued==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of sales quotes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Sales Quotes summary: Create sales quote description: Creates a new customer sales quote with the provided data and optional line items and prepayments. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_18 requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesQuoteDocument' required: true responses: '201': description: Sales quote created content: '*/*': schema: $ref: '#/components/schemas/SalesQuoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PRESUPUESTOSEMITIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-orders: get: tags: - Sales Orders summary: List sales orders description: >- Returns a paginated list of customer sales orders with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_19 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: issued==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of sales orders content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Sales Orders summary: Create sales order description: Creates a new customer sales order with the provided data and optional line items and payments. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_19 requestBody: content: application/json: schema: $ref: '#/components/schemas/OrderDocument' required: true responses: '201': description: Sales order created content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PEDIDOSCLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-invoices: get: tags: - Sales Invoices summary: List sales invoices description: >- Returns a paginated list of customer sales invoices with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The constraint `issued==true` is always enforced server-side. operationId: list_20 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: series==A;number=gt=100 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of sales invoices content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Sales Invoices summary: Create sales invoice description: >- Creates a new customer sales invoice with the provided data and optional line items and payments. Business logic (accounting, stock, DTE) runs in the legacy WAR via the internal commands gateway. The `issued` flag is forced to `true` server-side regardless of the request payload. operationId: create_20 requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '201': description: Sales invoice created content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-invoices/new: post: tags: - Sales Invoices summary: Prototype sales invoice for a creation form description: >- Returns a NON-PERSISTED sales invoice pre-populated with the backend defaults the legacy form applies on 'new invoice': currencies and daily exchange rate of the branch's company, default accounting ledger, automatic document/accounting dates per company configuration, loyalty point value, Verifactu draft state (lifecycle BOR + series BORRADOR) when the company has Verifactu active, a PROVISIONAL series/number pair (re-derived at persist time) and the authenticated user's employee as agent or optometrist. The response carries no `id`, `version` or audit fields. The optional JSON body supplies initialisation hints: `warehouseId` (defaults to the user's current branch) and `counterpartyId`. Caller must follow up with `POST /api/v2/sales-invoices` to actually persist the invoice. operationId: prepareCreateSalesInvoice requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Sales invoice prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Hint references an unknown entity (warehouse, counterparty) or the user has no default branch content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FACTURASEMITIDAS` permission or the requested warehouse is outside the user's scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-delivery-notes: get: tags: - Sales Delivery Notes summary: List sales delivery notes description: >- Returns a paginated list of customer sales delivery notes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_21 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: issued==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of sales delivery notes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Sales Delivery Notes summary: Create sales delivery note description: Creates a new customer sales delivery note with the provided data and optional line items and prepayments. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_21 requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' required: true responses: '201': description: Sales delivery note created content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ALBARANESENTREGA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-credit-notes: get: tags: - Sales Credit Notes summary: List sales credit notes description: >- Returns a paginated list of customer sales credit notes with envelope `{data, totalCount, skip, limit, hasMore}`. Internally these are invoices with `creditNote=true`; the discriminator is pre-applied and any user RSQL `filter` is ANDed on top. operationId: list_22 parameters: - name: filter in: query description: >- Additional RSQL filter, ANDed with the implicit `creditNote==true` discriminator. RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: series==R - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of sales credit notes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Sales Credit Notes summary: Create sales credit note description: >- Creates a customer sales credit note linked to an existing sales invoice. The `rectifiedInvoiceId` field is required. The WAR forces the `corrective` / `creditNote` discriminators on the Factura. operationId: create_22 requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '201': description: Sales credit note created content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: >- Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. Common cause: missing `rectifiedInvoiceId`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/return-causes: get: tags: - Return Causes summary: List return causes description: >- Returns a paginated list of return causes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_23 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of return causes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Return Causes summary: Create return cause description: Creates a new return cause. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_23 requestBody: content: application/json: schema: $ref: '#/components/schemas/ReturnCauseDocument' required: true responses: '201': description: Return cause created content: '*/*': schema: $ref: '#/components/schemas/ReturnCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/return-causes/new: post: tags: - Return Causes summary: Prototype return cause for a creation form description: >- Returns a non-persisted return cause pre-populated with backend defaults (`enabled=true`, current company, next `code`). Optional JSON hints: `companyId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/return-causes` afterwards to persist. operationId: prepareCreateReturnCause requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Return cause prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/ReturnCauseDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAUSADEVOLUCION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances: get: tags: - Remittances summary: List remittances description: Returns a paginated list of SEPA remittance headers. operationId: list_24 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: companyId==1 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: remittanceDate:desc example: remittanceDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of remittances content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing `VER_REMESA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Remittances summary: Create remittance description: Creates a remittance from selected candidates and generates the pain.008 XML attachment. operationId: create_24 parameters: - name: Idempotency-Key in: header description: Unique key for safely retrying this financial command required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/RemittanceDocument' required: true responses: '201': description: Remittance created content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/{id}/signed-sepa-xml: get: tags: - Remittances summary: Download signed SEPA XML description: Streams the bank-signed SEPA XML attachment when present. operationId: downloadRemittanceSignedSepaXml parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: Signed XML file bytes content: application/octet-stream: {} '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Remittance or signed XML attachment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Remittances summary: Upload signed SEPA XML description: Uploads the bank-signed XML file. Requires a generated SEPA XML to exist first. operationId: uploadRemittanceSignedSepaXml parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Signed XML file required: - file responses: '200': description: Signed XML stored content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/{id}/actions/regenerate-sepa-xml: post: tags: - Remittances summary: Regenerate SEPA XML description: Rebuilds the pain.008 XML attachment from the persisted lines. Support users only. operationId: regenerateRemittanceSepaXml parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: XML regenerated content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/{id}/actions/generate-payments: post: tags: - Remittances summary: Generate incoming payments description: Creates cobros for the selected remittance lines and marks them as C (paid). operationId: generateRemittancePayments parameters: - name: id in: path required: true schema: type: integer format: int64 - name: Idempotency-Key in: header description: Unique key for safely retrying this financial command required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/RemittanceGeneratePaymentsRequest' required: true responses: '200': description: Payments generated content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/ranges: get: tags: - Ranges summary: List ranges description: Returns a paginated list of ranges with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_25 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of ranges content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Ranges summary: Create range description: Creates a new range. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_25 requestBody: content: application/json: schema: $ref: '#/components/schemas/RangeDocument' required: true responses: '201': description: Range created content: '*/*': schema: $ref: '#/components/schemas/RangeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/ranges/new: post: tags: - Ranges summary: Prototype range for a creation form description: >- Returns a non-persisted range pre-populated with backend defaults. Optional hints include `companyId` and `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/ranges` afterwards to persist it. operationId: prepareCreateRange requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Range prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/RangeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_GAMAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-orders: get: tags: - Purchase Orders summary: List purchase orders description: >- Returns a paginated list of supplier purchase orders with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The constraint `issued==false` is always enforced server-side. operationId: list_26 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: counterpartyName==*Acme* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of purchase orders content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Purchase Orders summary: Create purchase order description: Creates a new supplier purchase order with the provided data and optional line items and payments. The `issued` flag is forced to `false` server-side regardless of the request payload. operationId: create_26 requestBody: content: application/json: schema: $ref: '#/components/schemas/OrderDocument' required: true responses: '201': description: Purchase order created content: '*/*': schema: $ref: '#/components/schemas/OrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PEDIDOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-invoices: get: tags: - Purchase Invoices summary: List purchase invoices description: >- Returns a paginated list of supplier purchase invoices with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The constraint `issued==false` is always enforced server-side. operationId: list_27 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: counterpartyName==*Acme* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of purchase invoices content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Purchase Invoices summary: Create purchase invoice description: Creates a new supplier purchase invoice with the provided data and optional line items and payments. The `issued` flag is forced to `false` server-side regardless of the request payload. operationId: create_27 requestBody: content: application/json: schema: $ref: '#/components/schemas/InvoiceDocument' required: true responses: '201': description: Purchase invoice created content: '*/*': schema: $ref: '#/components/schemas/InvoiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FACTURASRECIBIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/purchase-delivery-notes: get: tags: - Purchase Delivery Notes summary: List purchase delivery notes description: >- Returns a paginated list of supplier purchase delivery notes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The constraint `issued==false` is always enforced server-side. operationId: list_28 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: counterpartyName==*Acme* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of purchase delivery notes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Purchase Delivery Notes summary: Create purchase delivery note description: >- Creates a new supplier purchase delivery note with the provided data and optional line items and prepayments. The `issued` flag is forced to `false` server-side regardless of the request payload. operationId: create_28 requestBody: content: application/json: schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' required: true responses: '201': description: Purchase delivery note created content: '*/*': schema: $ref: '#/components/schemas/SalesDeliveryNoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ALBARANESCOMPRA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/products: get: tags: - Products summary: List products description: >- Returns a paginated list of products with envelope `{data, totalCount, skip, limit, hasMore}`. The listing does NOT include variants ÔÇö fetch a single product with `GET /{id}` to get the full graph. Default sort is `lastModifiedAt:desc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_29 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true;brandId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of products content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Products summary: Create product description: >- Creates a new product with at least one variant. Business logic (FK resolution, supplier-price denormalisation, stock initialisation, default-variant linkage) runs in the legacy WAR via the internal commands gateway. Returns the full graph of the created product with all assigned IDs. operationId: create_29 requestBody: content: application/json: schema: $ref: '#/components/schemas/ProductDocument' required: true responses: '201': description: Product created content: '*/*': schema: $ref: '#/components/schemas/ProductDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/products/images: post: tags: - Products summary: Upload temporary product images description: Uploads one or more images to the legacy temporary storage. Use the returned `temporaryImageId` values in `temporaryImageIds` or `defaultTemporaryImageId` when creating/updating a product. operationId: uploadImages parameters: - name: companyId in: query description: Company ID that owns the future/existing product required: true schema: type: integer format: int64 example: 1 - name: files in: query description: Image files to upload required: true schema: type: array items: type: string format: binary responses: '200': description: Temporary product images uploaded content: '*/*': schema: $ref: '#/components/schemas/ProductImageUploadResponse' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MODELOS` or `EDITAR_MODELOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/product-variants/search: post: tags: - Product Variants summary: Search product variants (document-form panel) description: >- Contextual SKU search for document forms. Matches name, description, barcode and reference ('*' = wildcard; exact barcode/reference matches first), extended to supplier price references when the company enables it. Applies the legacy eligibility rules: enabled products with a visible model state, company scope widened to the consolidated group when it shares products, zero-price exclusion on Venezuelan fiscal printer companies and, on the sales side, branch product lines, stock availability and lens blocking. Each row carries the company's searchable custom fields and base price list prices; request includeColumns=true once per form session to get the panel column metadata. Read-only. Prices are informational: lines are created through POST /api/v2/pricing/preview. operationId: searchProductVariants requestBody: content: application/json: schema: $ref: '#/components/schemas/ProductVariantSearchRequest' required: true responses: '200': description: Matching variants content: '*/*': schema: $ref: '#/components/schemas/ProductVariantSearchResponse' '400': description: Invalid request (unknown branch, missing q/barcode, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user cannot use the document forms nor view products content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/pricing/preview: post: tags: - Pricing summary: Resolve sales prices description: >- Resolves, per product, the tax-excluded unit price (base price list or product sheet), the commercial discount (percentage, lineal amount or tax-included final price), the applied price rule and the applicable insurer conditions, against a document context (branch, customer, price lists, date, currency). Stateless: nothing is persisted and eligibility is re-enforced server-side on save. Items resolve by productId or barcode (single-request scanner flow); per-item failures are reported inline via errorCode without failing the batch. Combos that depend on other lines already present on the document are resolved at save time, not here. operationId: previewPrices requestBody: content: application/json: schema: $ref: '#/components/schemas/PricePreviewRequest' required: true responses: '200': description: Resolved prices content: '*/*': schema: $ref: '#/components/schemas/PricePreviewResponse' '400': description: Invalid request (unknown warehouse/customer/price list, no items, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user cannot create or edit sales invoices content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists: get: tags: - Price Lists summary: List price lists description: >- Returns a paginated list of price lists with envelope `{data, totalCount, skip, limit, hasMore}`. Filter by kind with `priceListType==TB` (TB, TBF, DTO, COM), by side with `forSales==true` and by state with `active==true` / `draft==false`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_30 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: priceListType==DTO;active==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of price lists content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Price Lists summary: Create price list description: Creates a price list directly in finalised state (no draft phase). Prefer `POST /new` when the creation happens through a form that also attaches entries or combo conditions. operationId: create_30 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListDocument' required: true responses: '201': description: Price list created content: '*/*': schema: $ref: '#/components/schemas/PriceListDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/entries: get: tags: - Price Lists summary: List price list entries description: >- Paginated entries (per-product prices and discount rules) of one price list. Product entries carry `productId`; discount rules carry `ruleOrder` plus the category/brand/group/campaign scope. Filter rules with `ruleOrder=notnull=''`, combo scope with `comboConditionId==7`. operationId: listPriceListEntries parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: productName=like=*gafa* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: id:asc example: id:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of entries content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Price Lists summary: Create price list entry description: 'Creates one per-product entry. Requires `productId` and a value: `price` (finalPrice=true), `discountPercent` (finalPrice=false) or `factor` (TBF).' operationId: createPriceListEntry parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListEntryDocument' required: true responses: '201': description: Entry created content: '*/*': schema: $ref: '#/components/schemas/PriceListEntryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/entries/bulk: post: tags: - Price Lists summary: Bulk-assign price list entries description: >- Set-based price assignment over every product matched by the filters (categories, brands, groups, campaign, price range, description/reference/barcode). Mirrors the legacy 'assign to articles' batch action. Duplicates are de-duplicated server-side. Returns 204 (the operation is set-based; list the entries to see the result). operationId: bulkCreatePriceListEntries parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListBulkEntriesRequest' required: true responses: '204': description: Bulk assignment executed '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/entries/bulk-delete: post: tags: - Price Lists summary: Bulk-delete price list entries description: Removes every entry matched by the filters (same filter block as the bulk assignment). Returns the number of removed rows. operationId: bulkDeletePriceListEntries parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListBulkEntriesRequest' responses: '200': description: Entries removed content: '*/*': schema: $ref: '#/components/schemas/PriceListBulkOperationResponse' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/discount-rules: post: tags: - Price Lists summary: Create price list discount rules description: >- Creates one discount rule per combination of the provided category/brand/group lists, optionally scoped to a campaign or a combo condition. Pre-existing rules with the same scope are replaced; the response reports created and removed counts. Rules are listed through `GET /entries?filter=ruleOrder=notnull=''` and removed through `DELETE /discount-rules/{ruleOrder}`. operationId: createPriceListDiscountRules parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListDiscountRuleRequest' required: true responses: '201': description: Rules created content: '*/*': schema: $ref: '#/components/schemas/PriceListBulkOperationResponse' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/combo-conditions: get: tags: - Price Lists summary: List price list combo conditions description: 'Combo conditions of a COM price list: purchase requirements (`purchaseCondition=true`) and applied discounts (`purchaseCondition=false`).' operationId: listPriceListComboConditions parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 responses: '200': description: Combo conditions content: '*/*': schema: $ref: '#/components/schemas/PriceListComboConditionDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Price Lists summary: Create price list combo condition description: Adds a combo condition to a COM price list. Requires `purchaseCondition`; the server assigns a default name (Art├¡culo N / Regalo N) when none is provided. operationId: createPriceListComboCondition parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 requestBody: content: application/json: schema: $ref: '#/components/schemas/PriceListComboConditionDocument' required: true responses: '201': description: Combo condition created content: '*/*': schema: $ref: '#/components/schemas/PriceListComboConditionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/new: post: tags: - Price Lists summary: Create price list draft description: >- PERSISTS a new price list in draft mode (`draft=true`) and returns it with a real `id` ÔÇö unlike the non-persisting `/new` of other resources. The row must exist so entries, discount rules and combo conditions can be attached while the form is being filled; the first PUT finalises the draft. Hints: `priceListType` (required ÔÇö TB, TBF, DTO or COM), `forSales` (default true), `companyId` (defaults to the user's current company), `copyFromId` (duplicates the source price list including entries and combo conditions), `name`, `code`. Delete the draft with the regular DELETE to cancel. operationId: prepareCreatePriceList requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '201': description: Draft persisted content: '*/*': schema: $ref: '#/components/schemas/PriceListDocument' '400': description: Invalid hints (missing priceListType, unknown copyFromId, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-terms: get: tags: - Payment Terms summary: List payment terms description: >- Returns a paginated list of payment terms with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_31 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of payment terms content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Payment Terms summary: Create payment term description: Creates a new payment term. Business logic runs in the legacy WAR. operationId: create_31 requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentTermDocument' required: true responses: '201': description: Payment term created content: '*/*': schema: $ref: '#/components/schemas/PaymentTermDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-terms/new: post: tags: - Payment Terms summary: Prototype payment term for a creation form description: >- Returns a non-persisted payment term pre-populated with backend defaults (current company, `enabled=true`, one instalment). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/payment-terms` to persist. operationId: prepareCreatePaymentTerm requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Payment term prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/PaymentTermDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CONDICIONESPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-methods: get: tags: - Payment Methods summary: List payment methods description: >- Returns a paginated list of payment methods with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_32 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of payment methods content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Payment Methods summary: Create payment method description: >- Creates a new payment method. Behaviour flags that do not apply to the selected `paymentKind` are rejected with `400` (e.g. `requiresChange` outside cash kinds, `cardTerminal` outside card kinds, `taxPct` outside the foreign-currency kind). Business logic runs in the legacy WAR. operationId: create_32 requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentMethodDocument' required: true responses: '201': description: Payment method created content: '*/*': schema: $ref: '#/components/schemas/PaymentMethodDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/payment-methods/new: post: tags: - Payment Methods summary: Prototype payment method for a creation form description: >- Returns a non-persisted payment method pre-populated with backend defaults (current company, next free `code`, `enabled=true`, ledger posting enabled, usable for incoming documents). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/payment-methods` to persist. operationId: prepareCreatePaymentMethod requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Payment method prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/PaymentMethodDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_FORMASDEPAGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/outgoing-payments: get: tags: - Outgoing Payments summary: List outgoing payments description: Returns a paginated list of outgoing payments (pagos). The constraint `issued==false` is always enforced server-side. operationId: list_33 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: counterpartyId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of outgoing payments content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Outgoing Payments summary: Create outgoing payment description: Records an outgoing payment against a purchase invoice, order or delivery note. The `issued` flag is forced to `false` server-side so the new Cobro is correctly classified as outgoing cash. operationId: create_33 requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentDocument' required: true responses: '201': description: Outgoing payment created content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PAGOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Referenced parent entity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/origin-types: get: tags: - Origin Types summary: List origin types description: >- Returns a paginated list of claim origin types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_34 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of origin types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Origin Types summary: Create origin type description: Creates a new claim origin type. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_34 requestBody: content: application/json: schema: $ref: '#/components/schemas/OriginTypeDocument' required: true responses: '201': description: Origin type created content: '*/*': schema: $ref: '#/components/schemas/OriginTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/origin-types/new: post: tags: - Origin Types summary: Prototype origin type for a creation form description: >- Returns a non-persisted claim origin type pre-populated with backend defaults (`enabled=true`, current company). Optional JSON hints: `companyId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/origin-types` afterwards to persist. operationId: prepareCreateOriginType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Origin type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/OriginTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPOORIGEN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/optical-orders: get: tags: - Optical Orders summary: List optical orders description: >- Returns a paginated list of optical orders with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. The list payload does NOT include the nested per-eye prescription or lens add-ons; fetch the order by id for the full shape. operationId: list_35 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: customerId==123;assembled==false - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of optical orders content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Optical Orders summary: Create optical order description: >- Creates a new optical order with header fields and the optional per-eye prescription. Business logic (stock reservations, production routing) runs in the legacy WAR via the internal commands gateway. operationId: create_35 requestBody: content: application/json: schema: $ref: '#/components/schemas/OpticalOrderDocument' required: true responses: '201': description: Optical order created content: '*/*': schema: $ref: '#/components/schemas/OpticalOrderDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/optical-orders/new: post: tags: - Optical Orders summary: Prototype optical order for a creation form description: Returns a non-persisted optical order prototype pre-filled with the authenticated user's default branch and the current date. The response carries no `id`, `version` or audit fields. operationId: prepareCreateOpticalOrder responses: '200': description: Optical order prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/OpticalOrderDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ENCARGO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/notes: get: tags: - Notes summary: List notes description: Returns a paginated list of notes. Use RSQL filters `ownerType` and `ownerId` to scope notes to their owner entity. Default sort is `createdAt:desc`. operationId: list_36 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: ownerType==customer-profiles;ownerId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: createdAt:desc example: createdAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of notes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing read permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Notes summary: Create note description: Creates a new note attached to a customer or customer profile. Set `ownerType` (`customers` | `customer-profiles`) and `ownerId` to bind the note. operationId: create_36 requestBody: content: application/json: schema: $ref: '#/components/schemas/NoteDocument' required: true responses: '201': description: Note created content: '*/*': schema: $ref: '#/components/schemas/NoteDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing edit permission on customers or customer profiles content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets: get: tags: - Loyalty Wallets summary: List loyalty wallets description: >- Returns a paginated list of loyalty wallets with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_37 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of loyalty wallets content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Loyalty Wallets summary: Create loyalty wallet description: >- Creates a new loyalty wallet. Business logic runs in the legacy WAR. `code` is optional: when omitted the WAR assigns the next sequential company-scoped code (same rule as `POST /loyalty-wallets/new`). Optional `members` links customers on creation (`null` leaves empty; `[]` clears; list replaces). `counterpartyAccountId` sets the owner when `members` is omitted. Optional `pointsBalance` seeds an initial manual movement. operationId: create_37 requestBody: content: application/json: schema: $ref: '#/components/schemas/LoyaltyWalletDocument' required: true responses: '201': description: Loyalty wallet created content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Loyalty Wallets summary: Bulk delete loyalty wallets description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteLoyaltyWallets requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Loyalty Wallets summary: Bulk patch loyalty wallets description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `enabled`, `description`.' operationId: bulkPatchLoyaltyWallets requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets/{id}/change-points: post: tags: - Loyalty Wallets summary: Change loyalty wallet balance description: Adds or removes points from the wallet via a manual ledger movement. REMOVE operations additionally require the `REMOVE_PUNTOS_MANUAL` permission on the legacy WAR side. operationId: changeLoyaltyWalletPoints parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 requestBody: content: application/json: schema: $ref: '#/components/schemas/PointsChangeDocument' required: true responses: '200': description: Loyalty wallet updated with new balance content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CARTERAPUNTOS` permission or `REMOVE_PUNTOS_MANUAL` for REMOVE operations content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets/{id}/change-members: post: tags: - Loyalty Wallets summary: Change loyalty wallet members description: Adds or removes a customer from the shared wallet without replacing the full `members` collection. Use `customerOwner=true` on ADD to set the owner. operationId: changeLoyaltyWalletOwners parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 requestBody: content: application/json: schema: $ref: '#/components/schemas/LoyaltyWalletMemberChangeDocument' required: true responses: '200': description: Loyalty wallet updated with new membership content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets/new: post: tags: - Loyalty Wallets summary: Prototype loyalty wallet for a creation form description: >- Returns a non-persisted loyalty wallet pre-populated with backend defaults (current company, next sequential `code`, `enabled=true`). Optional JSON hints: `companyId`. Call `POST /api/v2/loyalty-wallets` to persist. operationId: prepareCreateLoyaltyWallet requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Loyalty wallet prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/LoyaltyWalletDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-batches/render: post: tags: - Product Labels summary: Render a label batch description: >- Renders the (edited) lines to a print job. With `Accept: application/json` (default) returns a `LabelPrintJobDocument` with the content base64-encoded (PDF or Zebra ZPL) plus `pageCount`, suitable for download, preview or QZ Tray. With `Accept: application/pdf` streams the raw PDF bytes inline (PDF formats only). operationId: renderLabelBatch parameters: - name: Accept in: header required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/LabelRenderRequest' required: true responses: '200': description: Rendered print job content: application/json: schema: $ref: '#/components/schemas/LabelPrintJobDocument' application/pdf: schema: $ref: '#/components/schemas/LabelPrintJobDocument' '400': description: Invalid request (unknown format, empty lines, ...) content: application/json: schema: $ref: '#/components/schemas/ProblemDetail' application/pdf: schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: application/json: schema: $ref: '#/components/schemas/ProblemDetail' application/pdf: schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: application/json: schema: $ref: '#/components/schemas/ProblemDetail' application/pdf: schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: application/json: schema: $ref: '#/components/schemas/ProblemDetail' application/pdf: schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-batches/preview: post: tags: - Product Labels summary: Resolve label prices description: >- Resolves barcode, description and prices (base price, discount, VAT and commercial rounding) for a set of products against a format, a base price list and a branch. Returns the priced lines to render the "Detalles de las etiquetas" table and the per-label preview. operationId: previewLabelBatch requestBody: content: application/json: schema: $ref: '#/components/schemas/LabelPreviewRequest' required: true responses: '200': description: Resolved label batch content: '*/*': schema: $ref: '#/components/schemas/LabelBatchDocument' '400': description: Invalid request (unknown format, missing branch, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/journal-entries: get: tags: - Journal Entries summary: List journal entries description: >- Returns a paginated list of journal entries with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `accountingDate:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_38 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: draft==false;predefinedDocument==false - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: accountingDate:desc example: accountingDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of journal entries content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Journal Entries summary: Create journal entry description: Creates a new manual journal entry via the internal commands gateway. operationId: create_38 requestBody: content: application/json: schema: $ref: '#/components/schemas/JournalEntryDocument' required: true responses: '201': description: Journal entry created content: '*/*': schema: $ref: '#/components/schemas/JournalEntryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/journal-entries/new: post: tags: - Journal Entries summary: Prototype journal entry for a creation form description: >- Returns a non-persisted journal entry pre-populated with backend defaults (`enabled=true`, `draft=true`, current company, default series and fiscal year). Optional JSON hints: `companyId`, `activityId`, `copyFromId`. Call `POST /api/v2/journal-entries` afterwards to persist. operationId: prepareCreateJournalEntry requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Journal entry prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/JournalEntryDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ASIENTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/item-types: get: tags: - Item Types summary: List item types description: Paginated list with optional RSQL filter and sort (default lastModifiedAt:desc). Child collections are omitted; use GET /{id} for associatedAccounts. operationId: list_39 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*Merc* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-12-31T23:59:59Z' responses: '200': description: Page of item types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Item Types summary: Create item type description: 'Persists via the internal commands gateway. associatedAccounts: null leaves empty; [] clears; list replaces.' operationId: create_39 requestBody: content: application/json: schema: $ref: '#/components/schemas/ItemTypeDocument' required: true responses: '201': description: Item type created content: '*/*': schema: $ref: '#/components/schemas/ItemTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/item-types/new: post: tags: - Item Types summary: Prototype an item type for a creation form description: 'Non-persisted defaults: current company, enabled=true. Optional JSON hints: companyId, itemCategory, copyFromId.' operationId: prepareCreateItemType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Item type prototype content: '*/*': schema: $ref: '#/components/schemas/ItemTypeDocument' '400': description: Hint references an unknown entity content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSARTICULOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-exits: get: tags: - Inventory Exits summary: List inventory exits description: >- Returns a paginated list of manual inventory exits (stock adjustments with `tipoDoc = SAL_MAN`). Supports RSQL filtering, sorting, `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_40 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: warehouseId==3;documentDate=ge=2026-01-01 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: documentDate:desc example: documentDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of inventory exits content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TRASPASOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Inventory Exits summary: Create inventory exit description: >- Creates a manual inventory exit. The line quantities are subtracted from the source warehouse stock immediately upon successful creation. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_40 requestBody: content: application/json: schema: $ref: '#/components/schemas/InventoryExitDocument' required: true responses: '201': description: Inventory exit created content: '*/*': schema: $ref: '#/components/schemas/InventoryExitDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TRASPASOSDIRECTOS` permission, or the `warehouseId` is outside the user's branch scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: Operation would leave a product with negative stock content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-entries: get: tags: - Inventory Entries summary: List inventory entries description: >- Returns a paginated list of manual inventory entries (stock adjustments with `tipoDoc = ENT_MAN`). Supports RSQL filtering, sorting, `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_41 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: warehouseId==3;documentDate=ge=2026-01-01 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: documentDate:desc example: documentDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of inventory entries content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TRASPASOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Inventory Entries summary: Create inventory entry description: >- Creates a manual inventory entry. The line quantities are added to the destination warehouse stock immediately upon successful creation. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_41 requestBody: content: application/json: schema: $ref: '#/components/schemas/InventoryEntryDocument' required: true responses: '201': description: Inventory entry created content: '*/*': schema: $ref: '#/components/schemas/InventoryEntryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TRASPASOSDIRECTOS` permission, or the `warehouseId` is outside the user's branch scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: Operation would leave a product with negative stock content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-counts: get: tags: - Inventory Counts summary: List inventory counts description: Returns a paginated list of inventory counts. Combine with `filter=stockBalanced==true` (or `false`) to narrow by lifecycle status. operationId: list_42 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: warehouseId==3;stockBalanced==false - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: documentDate:desc example: documentDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of inventory counts content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_INVENTARIOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Inventory Counts summary: Create inventory count description: >- Creates a draft inventory count. The server runs the `agruparYCalcularDiferencias` step and returns the computed differences without moving stock. Set `finalize=true` to commit the count immediately in the same transaction (requires `CUADRAR_STOCK`). operationId: create_42 requestBody: content: application/json: schema: $ref: '#/components/schemas/InventoryCountDocument' required: true responses: '201': description: Inventory count created (DRAFT or FINALIZED) content: '*/*': schema: $ref: '#/components/schemas/InventoryCountDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_INVENTARIOS` permission (or `CUADRAR_STOCK` when `finalize=true`) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: Operation would leave a product with negative stock during finalisation content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-counts/{id}/finalize: post: tags: - Inventory Counts summary: Finalize inventory count description: >- Confirms a DRAFT inventory count and generates the resulting stock adjustments (entry for positive deltas, exit for negative ones). Returns the count with `status = FINALIZED` and the populated `stockAdjustments` references. Idempotency is explicit: calling finalize on an already FINALIZED count returns 409. operationId: finalizeInventoryCount parameters: - name: id in: path description: Inventory count ID required: true schema: type: integer format: int64 example: 501 - name: If-Match in: header description: >- Optimistic locking. Send the current entity version (the value of the `ETag` header from the last GET / POST / PUT / PATCH response). If the server's stored version does not match, the request fails with `409 Conflict`. Both strong (`"3"`) and weak (`W/"3"`) forms are accepted. Send no header (or empty) to skip the version check. required: false schema: type: string example: '3' responses: '200': description: Inventory count finalized content: '*/*': schema: $ref: '#/components/schemas/InventoryCountDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CUADRAR_STOCK` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory count not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '409': description: Inventory count is already FINALIZED, or the supplied `If-Match` does not match the current version content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '422': description: Operation would leave a product with negative stock content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/incoming-payments: get: tags: - Incoming Payments summary: List incoming payments description: Returns a paginated list of incoming payments (cobros). The constraint `issued==true` is always enforced server-side. operationId: list_43 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: counterpartyId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of incoming payments content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Incoming Payments summary: Create incoming payment description: >- Records an incoming payment against an invoice, order, delivery note or quote. Exactly one of those parent IDs is required; `amount` must be > 0. The `issued` flag is forced to `true` server-side. operationId: create_43 requestBody: content: application/json: schema: $ref: '#/components/schemas/PaymentDocument' required: true responses: '201': description: Incoming payment created content: '*/*': schema: $ref: '#/components/schemas/PaymentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_COBROS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Referenced parent entity not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/groups: get: tags: - Groups summary: List groups description: Returns a paginated list of groups with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_44 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*Premium* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of groups content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Groups summary: Create group description: Creates a new group. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_44 requestBody: content: application/json: schema: $ref: '#/components/schemas/GroupDocument' required: true responses: '201': description: Group created content: '*/*': schema: $ref: '#/components/schemas/GroupDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/groups/new: post: tags: - Groups summary: Prototype group for a creation form description: >- Returns a non-persisted group pre-populated with backend defaults. Optional hints include `companyId` and `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/groups` afterwards to persist it. operationId: prepareCreateGroup requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Group prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/GroupDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_GRUPOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/equivalence-surcharge-types: get: tags: - Equivalence Surcharge Types summary: List equivalence surcharge types description: Paginated list with optional RSQL filter and sort (default lastModifiedAt:desc). Child collections are omitted; use GET /{id} for associatedAccounts. operationId: list_45 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*5* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-12-31T23:59:59Z' responses: '200': description: Page of equivalence surcharge types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Equivalence Surcharge Types summary: Create equivalence surcharge type description: 'Persists via the internal commands gateway. associatedAccounts: null leaves empty; [] clears; list replaces.' operationId: create_45 requestBody: content: application/json: schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' required: true responses: '201': description: Equivalence surcharge type created content: '*/*': schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/equivalence-surcharge-types/new: post: tags: - Equivalence Surcharge Types summary: Prototype an equivalence surcharge type for a creation form description: 'Non-persisted defaults: current company, enabled=true. Optional JSON hints: companyId, copyFromId.' operationId: prepareCreateEquivalenceSurchargeType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Equivalence surcharge type prototype content: '*/*': schema: $ref: '#/components/schemas/EquivalenceSurchargeTypeDocument' '400': description: Hint references an unknown entity content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSRE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/employee-positions: get: tags: - Employee Positions summary: List employee positions description: Returns a paginated list of employee store positions with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_46 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*Opto* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of employee positions content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Employee Positions summary: Create employee position description: Creates a new employee store position. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_46 requestBody: content: application/json: schema: $ref: '#/components/schemas/EmployeePositionDocument' required: true responses: '201': description: Employee position created content: '*/*': schema: $ref: '#/components/schemas/EmployeePositionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Employee Positions summary: Bulk delete employee positions description: >- Removes every id in `ids` as a single all-or-nothing transaction. If any id is missing or outside the user's company scope the whole operation is rolled back. There is no `If-Match` header on this endpoint. operationId: bulkDeleteEmployeePositions requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids`, malformed payload, or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Employee Positions summary: Bulk patch employee positions description: >- Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields are restricted to a whitelist (`enabled`, `blockType`, `description`, `commissionsEnabled`, identity (`code`, `name`), multi-tenant scope (`companyId`) and audit fields are rejected. If any id is missing or outside the user's company scope the whole operation is rolled back. operationId: bulkPatchEmployeePositions requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload, non-whitelisted field or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/employee-positions/new: post: tags: - Employee Positions summary: Prototype employee position for a creation form description: >- Returns a non-persisted employee position pre-populated with backend defaults (current company, next numeric `code`, `enabled=true`). Optional hints: `companyId`, `copyFromId`. Call `POST /api/v2/employee-positions` afterwards to persist. operationId: prepareCreateEmployeePosition requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Employee position prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/EmployeePositionDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_POSICIONEMPLEADOTIENDA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/document-statuses: get: tags: - Document Statuses summary: List document statuses description: >- Returns a paginated list of custom document statuses with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_47 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*pend* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of document statuses content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Document Statuses summary: Create document status description: Creates a new custom document status. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_47 requestBody: content: application/json: schema: $ref: '#/components/schemas/DocumentStatusDocument' required: true responses: '201': description: Document status created content: '*/*': schema: $ref: '#/components/schemas/DocumentStatusDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/document-statuses/new: post: tags: - Document Statuses summary: Prototype document status for a creation form description: >- Returns a non-persisted document status pre-populated with backend defaults (current company, default document family). Optional JSON hints: `companyId`, `documentKind`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/document-statuses` afterwards to persist. operationId: prepareCreateDocumentStatus requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Document status prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/DocumentStatusDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ESTADOSDOCUMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/departments: get: tags: - Departments summary: List departments description: Returns a paginated list of employee departments with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_48 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*Opto* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of departments content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Departments summary: Create department description: Creates a new employee department. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_48 requestBody: content: application/json: schema: $ref: '#/components/schemas/DepartmentDocument' required: true responses: '201': description: Department created content: '*/*': schema: $ref: '#/components/schemas/DepartmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Departments summary: Bulk delete departments description: >- Removes every id in `ids` as a single all-or-nothing transaction. If any id is missing or outside the user's company scope the whole operation is rolled back. There is no `If-Match` header on this endpoint. operationId: bulkDeleteDepartments requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids`, malformed payload, or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Departments summary: Bulk patch departments description: >- Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields are restricted to a whitelist (`enabled`, `blockType`, `description`); identity (`code`, `name`), multi-tenant scope (`companyId`) and audit fields are rejected. If any id is missing or outside the user's company scope the whole operation is rolled back. operationId: bulkPatchDepartments requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload, non-whitelisted field or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/departments/new: post: tags: - Departments summary: Prototype department for a creation form description: >- Returns a non-persisted department pre-populated with backend defaults (current company, next numeric `code`, `enabled=true`). Optional hints: `companyId`, `copyFromId`. Call `POST /api/v2/departments` afterwards to persist. operationId: prepareCreateDepartment requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Department prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/DepartmentDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_DEPARTAMENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/customers: get: tags: - Customers summary: List customers description: >- Returns a paginated list of customers with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_49 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: cif==A12345678 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of customers content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Customers summary: Create customer description: Creates a new customer (tercero). Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_49 requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomerDocument' required: true responses: '201': description: Customer created content: '*/*': schema: $ref: '#/components/schemas/CustomerDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CLIENTES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/customer-profiles: get: tags: - Customer Profiles summary: List customer profiles description: >- Returns a paginated list of customer profiles with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_50 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of customer profiles content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Customer Profiles summary: Create customer profile description: Creates a new customer profile. Business logic runs in the legacy WAR. operationId: create_50 requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomerProfileDocument' required: true responses: '201': description: Customer profile created content: '*/*': schema: $ref: '#/components/schemas/CustomerProfileDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Customer Profiles summary: Bulk delete customer profiles description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteCustomerProfiles requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Customer Profiles summary: Bulk patch customer profiles description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `enabled`, `allowsCredit`, `isInsurer`, `isSupplier`, `isCorporateDivision`.' operationId: bulkPatchCustomerProfiles requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/customer-profiles/new: post: tags: - Customer Profiles summary: Prototype customer profile for a creation form description: >- Returns a non-persisted customer profile pre-populated with backend defaults (`enabled=true`, current company, next `code`, empty `name`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/customer-profiles` afterwards to persist. operationId: prepareCreateCustomerProfile requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Customer profile prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CustomerProfileDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_PERFILDECLIENTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/custom-field-definitions: get: tags: - Custom Field Definitions summary: List custom field definitions description: >- Returns a paginated list of custom field definitions with envelope `{data, totalCount, skip, limit, hasMore}`. Optional `featureType` filter: JSON-backed (customers, optometry-exams, audiology-exams, contactology-fittings, contact-lens-exams) or EAV-backed bridge (product-models, product-variants, manufacturing-custom-fields; scoped to the caller's companies). Disabled definitions are hidden unless `includeDisabled=true`. Fixed ordering: featureType, displayOrder, apiName. operationId: list_51 parameters: - name: featureType in: query description: Filter by owning feature (public v2 nomenclature). required: false schema: type: string example: customers - name: includeDisabled in: query description: Include disabled definitions. required: false schema: type: boolean default: false example: false - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of custom field definitions content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Unknown featureType content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Custom Field Definitions summary: Create custom field definition description: >- Creates a new custom field definition for the given `featureType`. The `apiName` must be unique within the featureType. For `dataType=ENUM` the `options` array is accepted as an optional creation seed (each label becomes an option row); afterwards options are managed through the paginated `/options` sub-resource. EAV-backed featureTypes (product-models, product-variants, manufacturing-custom-fields) accept dataType COLOR, an optional `companyId` (defaults to the caller's current company) and store into ges_customfield until the ADR-003 Fase 3 migration. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_51 requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' required: true responses: '201': description: Custom field definition created content: '*/*': schema: $ref: '#/components/schemas/CustomFieldDefinitionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/custom-field-definitions/{definitionId}/options: get: tags: - Custom Field Definitions summary: List options of a custom field definition description: >- Returns a paginated page of the definition's options with envelope `{data, totalCount, skip, limit, hasMore}`, ordered by displayOrder then value. `search` filters by case-insensitive containment on the value ÔÇö use it for autocomplete over large catalogs instead of fetching everything. Disabled options are hidden unless `includeDisabled=true`. operationId: list_52 parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models - name: search in: query description: Case-insensitive containment filter on the option value. required: false schema: type: string example: vip - name: includeDisabled in: query description: Include disabled options. required: false schema: type: boolean default: false example: false - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of options content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Custom Field Definitions summary: Create option description: >- Adds one option to a dataType=ENUM (or COLOR for EAV-backed featureTypes) definition. The `value` must be unique within the definition (it is what entity writes store). `hex` is only accepted for COLOR definitions. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_52 parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomFieldOptionDocument' required: true responses: '201': description: Option created content: '*/*': schema: $ref: '#/components/schemas/CustomFieldOptionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/custom-field-definitions/{definitionId}/options/bulk: post: tags: - Custom Field Definitions summary: Bulk create options description: >- Adds up to 1000 options in one request (all-or-nothing: any invalid or duplicate entry rolls back the whole batch). Intended for imports of large catalogs; send multiple batches for bigger volumes. operationId: createBulk parameters: - name: definitionId in: path description: Custom field definition ID required: true schema: type: integer format: int64 example: 7 - name: featureType in: query description: >- Feature namespace of the definition id. REQUIRED for EAV-backed featureTypes (`product-models`, `product-variants`, `manufacturing-custom-fields`), whose ids live in ges_customfield. Omit it (or pass a JSON-backed featureType) to resolve the id against cf_definition. required: false schema: type: string example: product-models requestBody: content: application/json: schema: type: array items: $ref: '#/components/schemas/CustomFieldOptionDocument' required: true responses: '201': description: Options created (array, in request order) content: '*/*': schema: $ref: '#/components/schemas/CustomFieldOptionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAMPOSPERSONALIZADOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Custom field definition not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/coupon-types: get: tags: - Coupon Types summary: List coupon types description: >- Returns a paginated list of coupon types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_53 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of coupon types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Coupon Types summary: Create coupon type description: Creates a new coupon type. Business logic runs in the legacy WAR. `code` and `name` are required. operationId: create_53 requestBody: content: application/json: schema: $ref: '#/components/schemas/CouponTypeDocument' required: true responses: '201': description: Coupon type created content: '*/*': schema: $ref: '#/components/schemas/CouponTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Coupon Types summary: Bulk delete coupon types description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteCouponTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Coupon Types summary: Bulk patch coupon types description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `description`, `categoryIds`.' operationId: bulkPatchCouponTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/coupon-types/new: post: tags: - Coupon Types summary: Prototype coupon type for a creation form description: >- Returns a non-persisted coupon type pre-populated with backend defaults (current company, `enabled=true`, `allCategories=true`, `discountKind=P`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/coupon-types` to persist. operationId: prepareCreateCouponType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Coupon type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CouponTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOPIN` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/verifactu-configuration/new: post: tags: - Verifactu Configuration summary: Prototype an Verifactu configuration description: Returns form defaults and does not persist a configuration. operationId: prepareCreateVerifactuConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Non-persistent prototype content: '*/*': schema: $ref: '#/components/schemas/VerifactuConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONVERIFACTU permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/verifactu-configuration/certificate: post: tags: - Verifactu Configuration summary: Upload and validate the company PKCS#12 certificate description: Stages a .p12/.pfx certificate and returns an opaque certificateId. The active configuration changes only after a successful PUT. operationId: uploadVerifactuCertificate parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: password in: query description: PKCS#12 password required: true schema: type: string - name: replace in: query description: Replace an already staged certificate required: false schema: type: boolean default: true example: true requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: PKCS#12 certificate (.p12 or .pfx) required: - file responses: '201': description: Certificate validated and staged content: '*/*': schema: $ref: '#/components/schemas/VerifactuCertificateUploadResponse' '400': description: Missing file, invalid PKCS#12 or wrong password content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONVERIFACTU permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '413': description: Certificate exceeds 5 MB content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/sat-mexico-configuration/new: post: tags: - SAT Mexico Configuration summary: Prototype a Mexico SAT configuration description: Returns form defaults and does not persist a configuration. operationId: prepareCreateSatMexicoConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Non-persistent prototype content: '*/*': schema: $ref: '#/components/schemas/SatMexicoConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSATMEXICO permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/sat-mexico-configuration/certificate: post: tags: - SAT Mexico Configuration summary: Upload and validate the company CSD certificate (.cer) description: Stages a .cer file and returns an opaque certificateId. Upload the matching .key via /certificate-key before PUT. operationId: uploadSatMexicoCertificate parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: replace in: query description: Replace an already staged certificate required: false schema: type: boolean default: true example: true requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: CSD certificate (.cer) required: - file responses: '201': description: Certificate validated and staged content: '*/*': schema: $ref: '#/components/schemas/SatMexicoCertificateUploadResponse' '400': description: Missing, invalid or oversized .cer content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSATMEXICO permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/sat-mexico-configuration/certificate-key: post: tags: - SAT Mexico Configuration summary: Upload the company CSD private key (.key) description: Stages the .key file for a previously uploaded certificateId. operationId: uploadSatMexicoCertificateKey parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: certificateId in: query description: certificateId returned by /certificate required: true schema: type: string requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: CSD private key (.key) required: - file responses: '201': description: Private key staged content: '*/*': schema: $ref: '#/components/schemas/SatMexicoCertificateKeyUploadResponse' '400': description: Missing certificateId or invalid/oversized .key content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSATMEXICO permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/document-control-configuration/new: post: tags: - Document Control Configuration summary: Prototype a document control configuration description: 'Returns non-persistent form defaults for a company that may not have a configuration row yet. Does not write to the database. Typical create flow: POST /new, then PUT / to persist.' operationId: prepareCreateDocumentControlConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Non-persistent prototype content: '*/*': schema: $ref: '#/components/schemas/DocumentControlConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_EMPRESAS permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/chile-sii-configuration/new: post: tags: - Chile SII Configuration summary: Prototype a Chile SII configuration description: Returns form defaults and does not persist a configuration. operationId: prepareCreateChileSiiConfiguration parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Non-persistent prototype content: '*/*': schema: $ref: '#/components/schemas/ChileSiiConfigurationDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSIICHILE permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/chile-sii-configuration/certificate: post: tags: - Chile SII Configuration summary: Upload and validate the company PKCS#12 certificate description: Stages a .p12/.pfx certificate and returns an opaque certificateId. The active configuration changes only after a successful PUT. operationId: uploadChileSiiCertificate parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: password in: query description: PKCS#12 password required: true schema: type: string - name: replace in: query description: Replace an already staged certificate required: false schema: type: boolean default: true example: true requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: PKCS#12 certificate (.p12 or .pfx) required: - file responses: '201': description: Certificate validated and staged content: '*/*': schema: $ref: '#/components/schemas/ChileSiiCertificateUploadResponse' '400': description: Missing file, invalid PKCS#12 or wrong password content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSIICHILE permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside the authenticated scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '413': description: Certificate exceeds 5 MB content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/companies/{companyId}/chile-sii-configuration/caf: post: tags: - Chile SII Configuration summary: Upload and validate a CAF file description: Validates the CAF XML for the requested document type and persists it using the same business rules as the legacy JSF screen. operationId: uploadChileSiiCaf parameters: - name: companyId in: path description: Company ID required: true schema: type: integer format: int64 example: 3 - name: documentType in: query description: CAF document type required: true schema: type: string example: INVOICES requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: CAF XML file required: - file responses: '201': description: CAF validated and persisted content: '*/*': schema: $ref: '#/components/schemas/ChileSiiCafUploadResponse' '400': description: Invalid CAF file or document type content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Missing EDITAR_CONFIGURACIONSIICHILE permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Company is outside scope or configuration missing content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '413': description: CAF exceeds 2 MB content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/collections: get: tags: - Collections summary: List collections description: Returns a paginated list of collections with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_54 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of collections content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Collections summary: Create collection description: Creates a new collection. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_54 requestBody: content: application/json: schema: $ref: '#/components/schemas/CollectionDocument' required: true responses: '201': description: Collection created content: '*/*': schema: $ref: '#/components/schemas/CollectionDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/collections/new: post: tags: - Collections summary: Prototype collection for a creation form description: >- Returns a non-persisted collection pre-populated with backend defaults. Optional hints include `companyId` and `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/collections` afterwards to persist it. operationId: prepareCreateCollection requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Collection prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CollectionDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_LINEAS_PRODUCTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-types: get: tags: - Claim Types summary: List claim types description: >- Returns a paginated list of claim types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_55 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of claim types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Claim Types summary: Create claim type description: Creates a new claim type and its configured solutions. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_55 requestBody: content: application/json: schema: $ref: '#/components/schemas/ClaimTypeDocument' required: true responses: '201': description: Claim type created content: '*/*': schema: $ref: '#/components/schemas/ClaimTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-types/new: post: tags: - Claim Types summary: Prototype claim type for a creation form description: >- Returns a non-persisted claim type pre-populated with backend defaults (`enabled=true`, current company). Optional JSON hints: `companyId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/claim-types` afterwards to persist. operationId: prepareCreateClaimType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Claim type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/ClaimTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOTIPORECLAMO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-causes: get: tags: - Claim Causes summary: List claim causes description: >- Returns a paginated list of claim causes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_56 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of claim causes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Claim Causes summary: Create claim cause description: Creates a new claim cause. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_56 requestBody: content: application/json: schema: $ref: '#/components/schemas/ClaimCauseDocument' required: true responses: '201': description: Claim cause created content: '*/*': schema: $ref: '#/components/schemas/ClaimCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/claim-causes/new: post: tags: - Claim Causes summary: Prototype claim cause for a creation form description: >- Returns a non-persisted claim cause pre-populated with backend defaults (`enabled=true`, current company). Optional JSON hints: `companyId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/claim-causes` afterwards to persist. operationId: prepareCreateClaimCause requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Claim cause prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/ClaimCauseDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_RECLAMOCAUSANTE` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/categories: get: tags: - Categories summary: List categories description: >- Returns a paginated list of categories with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `treeLeft:asc` so the result is naturally tree-ordered. Use `filter=parentId=null=` to fetch roots, or `filter=parentId==42` to fetch the direct children of a given parent. operationId: list_57 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: parentId==42 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: treeLeft:asc example: treeLeft:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of categories content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Categories summary: Create category description: Creates a new category. Use `parentId` to attach it under an existing parent (omit for a root). Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_57 requestBody: content: application/json: schema: $ref: '#/components/schemas/CategoryDocument' required: true responses: '201': description: Category created content: '*/*': schema: $ref: '#/components/schemas/CategoryDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/categories/new: post: tags: - Categories summary: Prototype category for a creation form description: >- Returns a non-persisted category pre-populated with backend defaults for the authenticated user. Optional hints include `companyId`, `parentId`, `articleTypeId`, `vatTypeId`, `expenseAccountId`, `incomeAccountId` and `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/categories` afterwards to persist it. operationId: prepareCreateCategory requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Category prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CategoryDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CATEGORIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes: get: tags: - Cash Closes summary: List cash closes description: >- Returns a paginated list of cash register closes. Mirror the legacy JSF list defaults with `filter=draft==false;closeType==N` (limited users only see normal closes, not opening balances). Use `open==true` or `open==false` to list open or closed periods. operationId: list_58 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: draft==false;closeType==N;open==false;warehouseId==1 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: closeAt:desc example: closeAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of cash closes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Cash Closes summary: Create cash close description: >- Creates and optionally closes a cash register period. Set `needsRecalculation=true` (or call calculate first) when `closeAt` changed so totals are refreshed from underlying payments. Writable line fields: `countedAmount` per payment method; `withdrawals` when the branch tracks register withdrawals. operationId: create_58 requestBody: content: application/json: schema: $ref: '#/components/schemas/CashCloseDocument' required: true responses: '201': description: Cash close created content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes/{id}/calculate: post: tags: - Cash Closes summary: Calculate cash close totals description: >- Recomputes payment-method totals and period boundaries from underlying `Cobro` rows ({@code CajaService.calcularCierre}). Does not persist ÔÇö call PUT/POST afterwards to save counts and withdrawals. operationId: calculateCashClose parameters: - name: id in: path description: Cash close ID required: true schema: type: integer format: int64 example: 42 responses: '200': description: Calculated cash close (not persisted) content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes/{closeId}/withdrawals/{withdrawalId}/attachment: get: tags: - Cash Closes summary: Download withdrawal photo description: Streams the deposit receipt image attached to a cash withdrawal. operationId: downloadCashCloseWithdrawalAttachment parameters: - name: closeId in: path required: true schema: type: integer format: int64 - name: withdrawalId in: path required: true schema: type: integer format: int64 responses: '200': description: Image file bytes content: application/octet-stream: {} '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Cash close, withdrawal or attachment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Cash Closes summary: Upload withdrawal photo description: Stores a deposit receipt image for a cash withdrawal linked to this close. Accepts .gif, .jpg, .jpeg and .png up to 5 MiB (parity with JSF movCajaForm). operationId: uploadCashCloseWithdrawalAttachment parameters: - name: closeId in: path required: true schema: type: integer format: int64 - name: withdrawalId in: path required: true schema: type: integer format: int64 requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Deposit receipt image required: - file responses: '200': description: Attachment stored content: '*/*': schema: $ref: '#/components/schemas/AttachmentRef' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Cash Closes summary: Delete withdrawal photo description: Removes the deposit receipt image from a cash withdrawal. operationId: deleteCashCloseWithdrawalAttachment parameters: - name: closeId in: path required: true schema: type: integer format: int64 - name: withdrawalId in: path required: true schema: type: integer format: int64 responses: '204': description: Attachment deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes/new: post: tags: - Cash Closes summary: Prototype cash close for a creation form description: 'Returns a non-persisted cash close with backend defaults (branch, default close datetime, open=true). Optional JSON hints: `warehouseId`. Call `POST /api/v2/cash-closes` to persist.' operationId: prepareCreateCashClose requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Cash close prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cash-closes/calculate: post: tags: - Cash Closes summary: Calculate cash close totals (stateless) description: >- Recomputes payment-method totals for a not-yet-persisted cash close. Send a {@link CashCloseDocument} without {@code id} (at minimum {@code warehouseId} and {@code closeAt}). Parity with the legacy JSF "Calcular" action before the first save. Does not persist. operationId: calculateCashCloseStateless requestBody: content: application/json: schema: $ref: '#/components/schemas/CashCloseDocument' required: true responses: '200': description: Calculated cash close preview (not persisted) content: '*/*': schema: $ref: '#/components/schemas/CashCloseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAJAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/card-types: get: tags: - Card Types summary: List card types description: >- Returns a paginated list of card types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `lastModifiedAt:desc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_59 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of card types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Card Types summary: Create card type description: 'Creates a new card type. Business logic runs in the legacy WAR. `code` is optional: when omitted the WAR assigns the next sequential company-scoped code (same rule as `POST /card-types/new`).' operationId: create_59 requestBody: content: application/json: schema: $ref: '#/components/schemas/CardTypeDocument' required: true responses: '201': description: Card type created content: '*/*': schema: $ref: '#/components/schemas/CardTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Card Types summary: Bulk delete card types description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteCardTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Card Types summary: Bulk patch card types description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `enabled`.' operationId: bulkPatchCardTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/card-types/new: post: tags: - Card Types summary: Prototype card type for a creation form description: >- Returns a non-persisted card type pre-populated with backend defaults (current company, next sequential `code`, `enabled=true`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/card-types` to persist. operationId: prepareCreateCardType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Card type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CardTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOSTARJETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cancellation-causes: get: tags: - Cancellation Causes summary: List cancellation causes description: >- Returns a paginated list of cancellation causes with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_60 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*stock* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of cancellation causes content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Cancellation Causes summary: Create cancellation cause description: Creates a new cancellation cause. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_60 requestBody: content: application/json: schema: $ref: '#/components/schemas/CancellationCauseDocument' required: true responses: '201': description: Cancellation cause created content: '*/*': schema: $ref: '#/components/schemas/CancellationCauseDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/cancellation-causes/new: post: tags: - Cancellation Causes summary: Prototype cancellation cause for a creation form description: >- Returns a non-persisted cancellation cause pre-populated with backend defaults (`enabled=true`, current company, next `code`). Optional JSON hints: `companyId`, `warehouseId`, `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/cancellation-causes` afterwards to persist. operationId: prepareCreateCancellationCause requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Cancellation cause prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CancellationCauseDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAUSAANULACION` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/campaigns: get: tags: - Campaigns summary: List campaigns description: >- Returns a paginated list of campaigns with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `startDate:desc` so most recent campaigns appear first. Limit is capped at 200; skip is clamped to >= 0. operationId: list_61 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true;startDate=ge=2026-01-01 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: startDate:desc example: startDate:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of campaigns content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Campaigns summary: Create campaign description: Creates a new campaign. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_61 requestBody: content: application/json: schema: $ref: '#/components/schemas/CampaignDocument' required: true responses: '201': description: Campaign created content: '*/*': schema: $ref: '#/components/schemas/CampaignDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/campaigns/new: post: tags: - Campaigns summary: Prototype campaign for a creation form description: >- Returns a non-persisted campaign pre-populated with backend defaults. Optional hints include `companyId` and `copyFromId`. The response has no `id`, `version` or audit fields; call `POST /api/v2/campaigns` afterwards to persist it. operationId: prepareCreateCampaign requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Campaign prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/CampaignDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CAMPANIAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/calendars: get: tags: - Calendars summary: List calendars description: Returns a paginated list of calendars with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_62 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of calendars content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Calendars summary: Create calendar description: Creates a new calendar. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_62 requestBody: content: application/json: schema: $ref: '#/components/schemas/CalendarDocument' required: true responses: '201': description: Calendar created content: '*/*': schema: $ref: '#/components/schemas/CalendarDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/brands: get: tags: - Brands summary: List brands description: >- Returns a paginated list of brands with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. Limit is capped at 200; skip is clamped to >= 0. operationId: list_63 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: name=like=*Sony* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of brands content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Brands summary: Create brand description: Creates a new brand. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_63 requestBody: content: application/json: schema: $ref: '#/components/schemas/BrandDocument' required: true responses: '201': description: Brand created content: '*/*': schema: $ref: '#/components/schemas/BrandDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Brands summary: Bulk delete brands description: >- Removes every id in `ids` as a single all-or-nothing transaction. If any id is missing or outside the user's company scope the whole operation is rolled back. There is no `If-Match` header on this endpoint because a single ETag cannot represent a heterogeneous selection. The request body is mandatory; clients that cannot send a body on `DELETE` should fall back to the per-id endpoint `DELETE /api/v2/brands/{id}`. operationId: bulkDeleteBrands requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids`, malformed payload, or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Brands summary: Bulk patch brands description: >- Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields are restricted to a whitelist (`enabled`, `blockType`, `description`, `groupId`, `campaignId`); identity (`code`, `name`), multi-tenant scope (`companyId`) and audit fields are rejected. If any id is missing or outside the user's company scope the whole operation is rolled back. There is no `If-Match` header on this endpoint. operationId: bulkPatchBrands requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload, non-whitelisted field or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/brands/new: post: tags: - Brands summary: Prototype brand for a creation form description: >- Returns a non-persisted brand pre-populated with the authenticated user's defaults (current company, `enabled=true`, `blockType=null`). The response carries no `id`, `version` or audit fields. The optional JSON body supplies initialisation hints understood by the WAR; currently recognised: `companyId`, `groupId`, `campaignId` and `copyFromId` (replicates code/name/description from an existing brand). Caller must follow up with `POST /api/v2/brands` to actually persist the entity. operationId: prepareCreateBrand requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Brand prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/BrandDocument' '400': description: Hint references an unknown entity (group, campaign, ...) content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_MARCAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/associated-contact-types: get: tags: - Associated Contact Types summary: List associated contact types description: >- Returns a paginated list of associated contact types with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `name:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_64 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of associated contact types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Associated Contact Types summary: Create associated contact type description: Creates a new associated contact type. Business logic runs in the legacy WAR. operationId: create_64 requestBody: content: application/json: schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' required: true responses: '201': description: Associated contact type created content: '*/*': schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Associated Contact Types summary: Bulk delete associated contact types description: Removes every id in `ids` as a single all-or-nothing transaction. operationId: bulkDeleteAssociatedContactTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkDeleteRequest' required: true responses: '200': description: All entities deleted content: '*/*': schema: $ref: '#/components/schemas/BulkDeleteResponse' '400': description: Empty `ids` or unknown id content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `BORRAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Associated Contact Types summary: Bulk patch associated contact types description: 'Applies the same `patch` to every id in `ids` as a single all-or-nothing transaction. Editable fields: `enabled`, `linkApp`.' operationId: bulkPatchAssociatedContactTypes requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkPatchRequest' required: true responses: '200': description: All entities updated content: '*/*': schema: $ref: '#/components/schemas/BulkPatchResponse' '400': description: Empty `ids`/`patch`, malformed payload or non-whitelisted field content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/associated-contact-types/new: post: tags: - Associated Contact Types summary: Prototype associated contact type for a creation form description: >- Returns a non-persisted associated contact type pre-populated with backend defaults (`enabled=true`, `linkApp=true`, current company, empty `name`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/associated-contact-types` afterwards to persist. operationId: prepareCreateAssociatedContactType requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Associated contact type prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/AssociatedContactTypeDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOCONTACTOASOCIADO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointments: get: tags: - Appointments summary: List appointments description: >- Returns a paginated list of appointments / calendar events with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `lastModifiedAt:desc`. Use `filter=type==MEETING` or `filter=type==OPTICS_APPOINTMENT` to select a single event type. Limit is capped at 200; skip is clamped to >= 0. operationId: list_65 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: type==MEETING;startsAt=ge=2026-01-01T00:00:00Z - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of appointments content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Appointments summary: Create appointment description: Creates a new calendar appointment. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_65 requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentDocument' required: true responses: '201': description: Appointment created content: '*/*': schema: $ref: '#/components/schemas/AppointmentDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_EVENTO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointment-types: get: tags: - Appointment Types summary: List appointment types description: Returns a paginated list of appointment types with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_66 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of appointment types content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Appointment Types summary: Create appointment type description: Creates a new appointment type. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_66 requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentTypeDocument' required: true responses: '201': description: Appointment type created content: '*/*': schema: $ref: '#/components/schemas/AppointmentTypeDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOCITA` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/appointment-services: get: tags: - Appointment Services summary: List appointment services description: Returns a paginated list of appointment services with envelope `{data, totalCount, skip, limit, hasMore}`. Default sort is `name:asc`. Limit is capped at 200; skip is clamped to >= 0. operationId: list_67 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: appointmentTypeId==12 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: name:asc example: name:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of appointment services content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Appointment Services summary: Create appointment service description: Creates a new appointment service. Business logic runs in the legacy WAR via the internal commands gateway. operationId: create_67 requestBody: content: application/json: schema: $ref: '#/components/schemas/AppointmentServiceDocument' required: true responses: '201': description: Appointment service created content: '*/*': schema: $ref: '#/components/schemas/AppointmentServiceDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_TIPOCITASERVICIO` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/activities: get: tags: - Activities summary: List activities description: >- Returns a paginated list of accounting activities with envelope `{data, totalCount, skip, limit, hasMore}`. Supports optional RSQL `filter`, `sort` (default `code:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_68 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: enabled==true - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: code:asc example: code:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of activities content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Activities summary: Create activity description: Creates a new accounting activity via the internal commands gateway. operationId: create_68 requestBody: content: application/json: schema: $ref: '#/components/schemas/ActivityDocument' required: true responses: '201': description: Activity created content: '*/*': schema: $ref: '#/components/schemas/ActivityDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/activities/new: post: tags: - Activities summary: Prototype activity for a creation form description: >- Returns a non-persisted activity pre-populated with backend defaults (`enabled=true`, current company, next available `code`). Optional JSON hints: `companyId`, `copyFromId`. Call `POST /api/v2/activities` afterwards to persist. operationId: prepareCreateActivity requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Activity prototype with defaults content: '*/*': schema: $ref: '#/components/schemas/ActivityDocument' '400': description: Invalid prepare-create hints content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ACTIVIDADES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/accounting-accounts: get: tags: - Accounting Accounts summary: List accounting accounts description: Paginated list with optional RSQL filter and sort (default lastModifiedAt:desc). operationId: list_69 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: account=like=*43* - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: lastModifiedAt:desc example: lastModifiedAt:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-12-31T23:59:59Z' responses: '200': description: Page of accounting accounts content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' post: tags: - Accounting Accounts summary: Create accounting account description: >- Persists via the internal commands gateway. The full account number must match the company's configured length (typically 8 digits). Supply either `account` or `prefix`+`suffix`; when prefix/suffix are provided the server recomputes `account`. operationId: create_69 requestBody: content: application/json: schema: $ref: '#/components/schemas/AccountingAccountDocument' required: true responses: '201': description: Accounting account created content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '400': description: Validation error ÔÇö the request body or a query parameter failed constraint validation. The response payload includes a `errors` array with field-level details. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/accounting-accounts/new: post: tags: - Accounting Accounts summary: Prototype an accounting account for a creation form description: 'Non-persisted defaults: current company, enabled=true, blockType=null. Optional JSON hints: companyId, prefix, copyFromId.' operationId: prepareCreateAccountingAccount requestBody: content: application/json: schema: $ref: '#/components/schemas/JsonNode' responses: '200': description: Accounting account prototype content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '400': description: Hint references an unknown entity content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}: get: tags: - Users summary: Get a user operationId: get parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Users summary: Delete a user operationId: delete_67 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Users summary: Update a user (merge-patch) operationId: patch_64 parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/json: schema: type: object additionalProperties: {} required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions/templates/{featureType}: patch: tags: - Users summary: Change the list template applied to a feature for this user description: listTemplate is a named view_plantilla id (shared, or private of the TARGET user) or 'default' to clear the selection. operationId: updatePermissionsTemplate parameters: - name: id in: path required: true schema: type: integer format: int64 - name: featureType in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/TemplateUpdateRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions/modules/{moduleId}: patch: tags: - Users summary: Enable/disable a module (customized users only) operationId: updatePermissionsModule parameters: - name: id in: path required: true schema: type: integer format: int64 - name: moduleId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/ModuleUpdateRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions/matrix/{entryId}: patch: tags: - Users summary: Toggle one matrix cell (customized users only) description: >- entryId = SubModule enum name (parent row) or PermissionEnum name (OTROS child row); actionId = ALL or a TipoPermiso. Identifiers are whitelisted against the gesmo-permissions enums. Anti-escalation: granting requires the caller to hold the permission; revoking is unrestricted. operationId: updatePermissionsMatrix parameters: - name: id in: path required: true schema: type: integer format: int64 - name: entryId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/MatrixUpdateRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions/customization: patch: tags: - Users summary: Customize (copy role ÔåÆ private set) or assign an ERP role description: >- customized=true copies the role's permissions into an editable private set and detaches the role; customized=false assigns the role. Anti-escalation: the caller can only assign/copy roles whose permissions they hold themselves. operationId: updatePermissionsCustomization parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/json: schema: $ref: '#/components/schemas/CustomizationRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/ip-restrictions: patch: tags: - Users summary: Enable/disable IP restrictions operationId: setIpRestrictions parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/json: schema: $ref: '#/components/schemas/IpRestrictionsPatchRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/devices/{deviceId}: delete: tags: - Users summary: Revoke a device operationId: deleteDevice parameters: - name: id in: path required: true schema: type: integer format: int64 - name: deviceId in: path required: true schema: type: string responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Users summary: Update a device (trust/active) operationId: patchDevice parameters: - name: id in: path required: true schema: type: integer format: int64 - name: deviceId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/DevicePatchRequest' required: true responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/{id}: get: tags: - Remittances summary: Get remittance by ID description: Returns the remittance header, persisted lines and SEPA attachment metadata. operationId: getById_66 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: Remittance found content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Remittance not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' delete: tags: - Remittances summary: Delete remittance description: Deletes a remittance when none of its lines are already paid. This legacy entity has no optimistic-lock version, so `If-Match` is not supported. operationId: delete_68 parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '204': description: Remittance deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' patch: tags: - Remittances summary: Merge-patch remittance description: >- Updates mutable header fields only (`name`, `description`, `enabled`). Lines and remittance date are immutable. This legacy entity has no optimistic-lock version, so `If-Match` is not supported. operationId: patch_65 parameters: - name: id in: path required: true schema: type: integer format: int64 requestBody: content: application/merge-patch+json: schema: $ref: '#/components/schemas/JsonNode' required: true responses: '200': description: Remittance updated content: '*/*': schema: $ref: '#/components/schemas/RemittanceDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/{viewId}/available-fields: get: tags: - Views summary: Available fields for a view description: >- Returns every field eligible to be added to the view's plantilla: native FieldDefs (excluding INTERNAL ones) plus the tenant's custom fields. Each entry carries `inPlantilla` so the SPA can render which fields are already part of the user's current layout. operationId: listAvailableFields parameters: - name: viewId in: path description: Registered view identifier required: true schema: type: string example: brands-main responses: '200': description: Available field descriptors content: '*/*': schema: type: array items: $ref: '#/components/schemas/AvailableFieldDescriptor' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the entity's read permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: View not registered content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/views/users-main: get: tags: - Users summary: users-main view definition operationId: definition responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users: get: tags: - Users summary: List users (paginated) operationId: list_70 parameters: - name: skip in: query required: false schema: type: integer format: int32 default: 0 - name: limit in: query required: false schema: type: integer format: int32 default: 50 - name: search in: query required: false schema: type: string - name: roleId in: query required: false schema: type: string - name: active in: query required: false schema: type: boolean responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/permissions: get: tags: - Users summary: ERP permission matrix (role-inherited or customized) description: >- Projects the tenant's ERP permission model (core_role / core_usuario_permiso) onto the matrix contract: Module sections, SubModule rows, TipoPermiso columns, plus the per-feature list-template selection. Labels are stable i18n keys; the SPA translates them. Changes apply to live sessions on the next token refresh. operationId: permissions parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/access-authentication: get: tags: - Users summary: Access & authentication view (password, IP, sessions, devices, events) operationId: accessAuthentication parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/summary: get: tags: - Users summary: Users header counters operationId: summary responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/companies: get: tags: - Users summary: Company/branch options for the invite dialog operationId: companies responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/stock: get: tags: - Stock summary: List stock snapshots description: >- Returns a paginated list of stock rows with envelope `{data, totalCount, skip, limit, hasMore}`. Scoped to the user's warehouses ({@code sucursalIds} claim). Supports optional RSQL `filter`, `sort` (default `barcode:asc`), `skip`/`limit` pagination and `modifiedAfter`/`modifiedBefore` bookends. operationId: list_71 parameters: - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: warehouseId==3;quantity=gt=0 - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: barcode:asc example: barcode:asc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of stock rows content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_STOCK` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/stock/{id}: get: tags: - Stock summary: Get stock row by composite ID description: Returns a single stock snapshot. The path parameter uses the legacy composite key `variantId_warehouseId` (e.g. `12045_3`). operationId: getById_67 parameters: - name: id in: path description: Composite stock id (variantId_warehouseId) required: true schema: type: string example: '12045_3' responses: '200': description: Stock row found content: '*/*': schema: $ref: '#/components/schemas/StockDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_STOCK` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Stock row not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/schema: get: tags: - Schema summary: List registered entities description: Returns the entity names that have a registered FieldDef catalog. Use one of these as the path variable on GET /{entity}. operationId: listSchemaEntities responses: '200': description: Alphabetically sorted list of entity names content: '*/*': schema: type: array items: type: string '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/schema/{entity}: get: tags: - Schema summary: Get field descriptors for an entity description: Returns the list of non-INTERNAL field descriptors for the given entity (use the internal Spanish entity name, e.g. "Factura", "Pedido", "Tercero"). operationId: getSchemaForEntity parameters: - name: entity in: path description: Internal entity name (Spanish) required: true schema: type: string example: Factura responses: '200': description: Field descriptors for the entity content: '*/*': schema: type: array items: $ref: '#/components/schemas/FieldDescriptor' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Entity not registered in the FieldDefRegistry content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/scheduling/calendars/{id}/free-slots: get: tags: - Free Slots summary: Get free slots of a calendar description: > Returns the bookable slots of a calendar for a date range, grouped by day. The whole computation is performed by `gesmo-scheduling-core`, the same engine the booking guard uses on write, so what this endpoint offers and what a `POST /api/v2/scheduling/events` accepts cannot drift apart. `timezone` is mandatory and explicit: the grid is built in the IANA zone you ask for and `startAt` / `endAt` carry that zone's offset. There is no server default ÔÇö tenants live in Europe/Madrid, America/Panama and America/Costa_Rica, and the same calendar is read from all three. Every requested day is present in the response, with an empty `slots` list when there is nothing to offer: "closed that day" and "outside the range you asked for" are different answers. Restricting by staff is optional. `employeeId` / `employeeIds` are the canonical names; `trabajadorId` / `trabajadorIds` and the GHL spellings `userId` / `userIds` are accepted as aliases and merged into one set. The range is capped at 31 days. operationId: getCalendarFreeSlots parameters: - name: id in: path description: Calendar ID required: true schema: type: integer format: int64 example: 2 - name: startDate in: query description: First day of the range, inclusive, read in `timezone` (YYYY-MM-DD) required: true schema: type: string example: '2026-07-27' - name: endDate in: query description: Last day of the range, inclusive, read in `timezone` (YYYY-MM-DD). Defaults to `startDate`. required: false schema: type: string example: '2026-08-02' - name: timezone in: query description: IANA timezone the grid is computed in. Mandatory. required: true schema: type: string example: Europe/Madrid - name: employeeId in: query description: Restrict the answer to one employee (GHL `userId`) required: false schema: type: integer format: int64 example: 42 - name: employeeIds in: query description: Restrict the answer to several employees (GHL `userIds`) required: false schema: type: array items: type: integer format: int64 - name: trabajadorId in: query description: Alias of `employeeId` required: false schema: type: integer format: int64 example: 42 - name: trabajadorIds in: query description: Alias of `employeeIds` required: false schema: type: array items: type: integer format: int64 - name: userId in: query description: GHL alias of `employeeId` required: false schema: type: integer format: int64 example: 42 - name: userIds in: query description: GHL alias of `employeeIds` required: false schema: type: array items: type: integer format: int64 responses: '200': description: Availability for the requested range content: '*/*': schema: $ref: '#/components/schemas/FreeSlotsResponse' '400': description: Missing or unparseable timezone / dates, inverted range, or a range longer than 31 days content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CALENDARIOUI` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Calendar not found or outside the caller's company scope content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/sales-invoices/{id}/capabilities: get: tags: - Sales Invoices summary: Get sales invoice editability matrix description: >- Returns the server-resolved editability matrix for the invoice: which field groups (header, counterparty, amounts, unit prices, manual discounts, products, quantities, accounting, payments, insurer amounts, cost centers) and actions (edit, delete) are allowed for the current document state and the authenticated user's permissions, with a stable `code` and human-readable `reason` for every denied entry. Mirrors the legacy JSF lock/permission rules (TipoBloqueo, Verifactu lifecycle, OLA mode, Venezuelan fiscal printer, credit-note types). Purely informative: the server re-validates every write regardless. operationId: getSalesInvoiceCapabilities parameters: - name: id in: path description: Sales invoice ID required: true schema: type: integer format: int64 example: 123 responses: '200': description: Editability matrix content: '*/*': schema: $ref: '#/components/schemas/InvoiceCapabilitiesDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_FACTURASEMITIDAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Sales invoice not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/{id}/sepa-xml: get: tags: - Remittances summary: Download generated SEPA XML description: Streams the generated pain.008 XML attachment. operationId: downloadRemittanceSepaXml parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': description: XML file bytes content: application/octet-stream: {} '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Remittance or XML attachment not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/remittances/candidates: get: tags: - Remittances summary: List remittance candidates description: Pending invoice balances and unpaid installments eligible for a new remittance. operationId: listRemittanceCandidates parameters: - name: companyId in: query description: Owning company ID required: true schema: type: integer format: int64 - name: fromDate in: query description: Inclusive start date (yyyy-MM-dd) required: true schema: type: string - name: toDate in: query description: Inclusive end date (yyyy-MM-dd) required: true schema: type: string - name: counterpartyName in: query description: Optional debtor name contains filter required: false schema: type: string - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 responses: '200': description: Candidate rows content: '*/*': schema: type: array items: $ref: '#/components/schemas/RemittanceCandidateDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/valuation: get: tags: - Price Lists summary: Get price list stock valuation description: >- Values the on-hand stock of a branch for every product covered by the price list: units, purchase value, base sale value and the sale value after applying this price list. Mirrors the 'Valoraci├│n' panel of the legacy dialog. operationId: getPriceListValuation parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: warehouseId in: query description: Branch (sucursal) to value required: true schema: type: integer format: int64 example: 3 responses: '200': description: Valuation computed content: '*/*': schema: $ref: '#/components/schemas/PriceListValuationResponse' '400': description: Missing warehouseId content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/loyalty-wallets/{id}/transactions: get: tags: - Loyalty Wallets summary: List loyalty wallet transactions description: >- Returns a paginated ledger of points movements for the given wallet. Supports the same RSQL `filter`, `sort`, `skip`/`limit` and `modifiedAfter`/`modifiedBefore` parameters as the main listing. operationId: listLoyaltyWalletTransactions parameters: - name: id in: path description: Loyalty wallet ID required: true schema: type: integer format: int64 example: 42 - name: filter in: query description: >- RSQL filter expression. Allows filtering by any field exposed in the entity's field catalog. **Comparison operators** - `==` equals ÔÇö `series==F` - `!=` not equals ÔÇö `series!=F` - `=gt=` greater than ÔÇö `total=gt=1000` - `=ge=` greater or equal ÔÇö `total=ge=1000` - `=lt=` less than ÔÇö `total=lt=1000` - `=le=` less or equal ÔÇö `total=le=1000` - `=like=` contains, with `*` as wildcard ÔÇö `name=like=*Garcia*` - `=in=` value in list ÔÇö `series=in=(A,B,C)` - `=out=` value not in list ÔÇö `status=out=(VOID,DRAFT)` - `=null=` is null ÔÇö `paidAt=null=true` - `=notnull=` is not null ÔÇö `paidAt=notnull=true` - `=between=` between two values ÔÇö `documentDate=between=(2026-01-01,2026-12-31)` **Logical composition** - `;` AND ÔÇö `series==F;total=gt=1000` - `,` OR ÔÇö `status==OPEN,status==SENT` - `()` grouping ÔÇö `(status==OPEN,status==SENT);total=gt=1000` **Discoverability** The list of filterable fields, allowed operators per type and UI hints is exposed at `GET /api/v2/schema/{Entity}` (use the internal Spanish entity name, for example `Factura`, `Pedido`, `Tercero`). required: false schema: type: string example: type==M - name: sort in: query description: >- Sort specification. Format `field:dir` (canonical) or `field,dir` (legacy). Multiple sort keys are separated by `;`. `dir` is `asc` (default) or `desc`. Examples: `lastModifiedAt:desc`, `documentDate:desc;number:asc`. required: false schema: type: string default: date:desc example: date:desc - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 - name: modifiedAfter in: query description: Restrict results to records whose `lastModifiedAt` is greater than or equal to this ISO 8601 timestamp (e.g. `2026-01-01T00:00:00Z`). ANDed with the `filter` expression if both are sent. required: false schema: type: string example: '2026-01-01T00:00:00Z' - name: modifiedBefore in: query description: Restrict results to records whose `lastModifiedAt` is less than or equal to this ISO 8601 timestamp. ANDed with the `filter` expression if both are sent. required: false schema: type: string responses: '200': description: Page of points transactions content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '400': description: Invalid filter or sort expression content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CARTERAPUNTOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Loyalty wallet not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-formats: get: tags: - Product Labels summary: List label formats description: >- Returns the catalog of product-label formats with envelope `{data, totalCount, skip, limit, hasMore}`. Optional filters: `material` (PUNCHED/CONTINUOUS), `medium` (PDF/ZEBRA_ZPL) and `favorite`. Sorted by name. operationId: listLabelFormats parameters: - name: material in: query description: Filter by physical media required: false schema: type: string example: PUNCHED - name: medium in: query description: Filter by output medium required: false schema: type: string example: PDF - name: favorite in: query description: Filter by the current user's favourite flag required: false schema: type: boolean example: true - name: skip in: query description: Number of records to skip from the start of the result set (offset). Clamped to >= 0. required: false schema: type: integer format: int32 default: 0 example: 0 - name: limit in: query description: Maximum number of records to return per page. Hard cap of 200; values above are silently clamped down. required: false schema: type: integer format: int32 default: 50 example: 50 responses: '200': description: Page of label formats content: '*/*': schema: $ref: '#/components/schemas/PageResponse' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-formats/{code}: get: tags: - Product Labels summary: Get label format by code description: Returns a single label format by its stable code. operationId: getLabelFormat parameters: - name: code in: path description: Label format code required: true schema: type: string example: punched-3x8 responses: '200': description: Label format found content: '*/*': schema: $ref: '#/components/schemas/LabelFormatDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Label format not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/label-formats/{code}/thumbnail: get: tags: - Product Labels summary: Get label format thumbnail description: Returns the PNG thumbnail preview of the label format. operationId: getLabelFormatThumbnail parameters: - name: code in: path description: Label format code required: true schema: type: string example: punched-3x8 responses: '200': description: Thumbnail image (PNG) content: image/png: schema: type: string format: byte '401': description: Missing or invalid JWT (Bearer token). content: image/png: schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `CREAR_ETIQUETAS` permission content: image/png: schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Label format or thumbnail not found content: image/png: schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: image/png: schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-exits/{id}: get: tags: - Inventory Exits summary: Get inventory exit by ID description: Returns a single inventory exit including its `lines`. The response carries a strong `ETag` header with the current version. operationId: getById_68 parameters: - name: id in: path description: Inventory exit ID required: true schema: type: integer format: int64 example: 1043 responses: '200': description: Inventory exit found content: '*/*': schema: $ref: '#/components/schemas/InventoryExitDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TRASPASOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory exit not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/inventory-entries/{id}: get: tags: - Inventory Entries summary: Get inventory entry by ID description: Returns a single inventory entry including its `lines`. The response carries a strong `ETag` header with the current version. operationId: getById_69 parameters: - name: id in: path description: Inventory entry ID required: true schema: type: integer format: int64 example: 1042 responses: '200': description: Inventory entry found content: '*/*': schema: $ref: '#/components/schemas/InventoryEntryDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_TRASPASOS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Inventory entry not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/catalogs: get: tags: - Catalogs summary: List catalog definitions description: Machine-readable inventory of registered catalog keys and the contextual parameters accepted by each one. Use this contract instead of hardcoding dynamic-catalog requirements in the SPA. operationId: listCatalogDefinitions responses: '200': description: Catalog definitions content: '*/*': schema: type: array items: $ref: '#/components/schemas/CatalogDefinition' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/catalogs/{catalog}: get: tags: - Catalogs summary: List a dynamic catalog description: >- Returns the `[{code, name}, ...]` array used by AG Grid Set Filters and form selects/autocompletes. Returned values are already translated according to `Accept-Language` (when applicable). Supply the optional `q` to filter for autocomplete and `limit` (default 50, cap 500) to control payload size. For company-scoped catalogs such as `accountingAccount`, supply `companyId` to restrict entries to that company (must be within the JWT company scope). Contextual catalogs additionally accept filter parameters mirroring the legacy autocompletes (e.g. `forSales`, `priceListType`, `documentKind`); a missing mandatory filter is rejected with `400`. Cached privately for 1 minute only when no `q`, `companyId` nor contextual filter is supplied; not cached otherwise. operationId: getCatalog parameters: - name: catalog in: path description: Catalog key (matches `FilterParams.catalog` on a `ColumnDefinition` or the entity stem in singular for FK lookups, e.g. `gender`, `brand`, `customer`). required: true schema: type: string example: gender - name: q in: query description: Optional autocomplete text. Case-insensitive `contains` match on name and code. Trimmed; ignored when blank. required: false schema: type: string example: sony - name: limit in: query description: Maximum entries to return. Default 50, hard cap 500. required: false schema: type: integer format: int32 default: 50 example: 50 - name: companyId in: query description: Optional company scope for company-scoped catalogs (e.g. accountingAccount). Must belong to the JWT company set. required: false schema: type: integer format: int64 example: 2 responses: '200': description: Catalog entries content: '*/*': schema: $ref: '#/components/schemas/CatalogEntry' '400': description: A mandatory contextual filter is missing content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Unknown catalog key content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/accounting-accounts/prefix-hints: get: tags: - Accounting Accounts summary: List prefix hints while typing a new account code description: >- Hierarchical chart-of-accounts hints mirroring the legacy JSF create dialog (`changeCuenta`). As each digit is typed, returns rollup accounts and sub-accounts whose prefix matches the typed hierarchy for the given company. operationId: prefixHints parameters: - name: digits in: query description: Account digits typed so far (numeric only) required: true schema: type: string example: 430 - name: companyId in: query description: Owning company ID required: true schema: type: integer format: int64 example: 1 responses: '200': description: Prefix hierarchy hints content: '*/*': schema: $ref: '#/components/schemas/AccountingAccountDocument' '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `VER_CUENTASCONTABLES` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/users/{id}/ip-restrictions/ips/{ipId}: delete: tags: - Users summary: Remove an authorized IP operationId: deleteAuthorizedIp parameters: - name: id in: path required: true schema: type: integer format: int64 - name: ipId in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/user-invitations/{id}: delete: tags: - User Invitations summary: Cancel a pending invitation operationId: cancel parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' /api/v2/price-lists/{id}/discount-rules/{ruleOrder}: delete: tags: - Price Lists summary: Delete price list discount rule description: Removes the discount rule identified by its `ruleOrder`, optionally scoped to a combo condition via `comboConditionId`. operationId: deletePriceListDiscountRule parameters: - name: id in: path description: Price list ID required: true schema: type: integer format: int64 example: 5 - name: ruleOrder in: path description: Rule order (see the `ruleOrder` field of the entries) required: true schema: type: integer format: int32 example: 1 - name: comboConditionId in: query description: Combo condition the rule belongs to (COM price lists) required: false schema: type: integer format: int64 responses: '204': description: Rule deleted '401': description: Missing or invalid JWT (Bearer token). content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '403': description: Authenticated user is missing the `EDITAR_TARIFAS` permission content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '404': description: Price list not found content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' '500': description: Unexpected server error. Includes legacy WAR failures that are not classified as `502` / `503` / `504`. content: '*/*': schema: $ref: '#/components/schemas/ProblemDetail' components: schemas: WarehouseTypeDocument: type: object description: Warehouse type (TiendaTipoTienda) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TiendaTipoTienda is not versioned ÔÇö always null) readOnly: true code: type: string description: >- Business code (unique, company-scoped, max 2 characters). Optional on create ÔÇö the WAR assigns the next sequential value via `getNextCodigo` when omitted. Pre-filled by `POST /warehouse-types/new`. example: '11' name: type: string description: Display name example: ├ôptica description: type: string description: Description enabled: type: boolean description: Whether the warehouse type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true ProblemDetail: type: object properties: type: type: string format: uri title: type: string status: type: integer format: int32 detail: type: string instance: type: string format: uri properties: type: object additionalProperties: {} VisualTherapyTemplateDocument: type: object description: Visual therapy exercise template (EjercicioTerapiaVisualPlantilla) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true name: type: string description: Display name example: Convergence exercise description: type: string description: Short description content: type: string description: Rich HTML exercise instructions ({@code texto}) enabled: type: boolean description: Whether the template is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true warehouseId: type: integer format: int64 description: Branch / warehouse ID ({@code sucursal_id}) example: 3 warehouseName: type: string description: Branch / warehouse name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true VisitReasonDocument: type: object description: Visit reason (MotivoVisita) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (MotivoVisita is not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique, company-scoped). Optional on create ÔÇö the WAR assigns the next sequential value via `getNextCodigo` when omitted. Pre-filled by `POST /visit-reasons/new`. example: '1001' name: type: string description: Display name example: Routine check-up description: type: string description: Description enabled: type: boolean description: Whether the visit reason is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true ViewLayoutColumn: type: object description: A single column entry of the layout. properties: field: type: string description: Column apiName (native FieldDef or customFields.). example: name width: type: integer format: int32 description: Pixel width persisted on view_plantilla_campo. ViewLayoutUpdateRequest: type: object description: 'View layout update: user''s desired column selection (order + width).' properties: columns: type: array description: Visible columns in user-defined order. items: $ref: '#/components/schemas/ViewLayoutColumn' PinnedColumns: type: object description: Pinned (frozen) columns by side. properties: left: type: array description: Fields pinned to the left. items: type: string right: type: array description: Fields pinned to the right. items: type: string SortModel: type: object description: 'Single sort directive: column id + asc/desc.' properties: colId: type: string description: Matches a `field` of the column definitions. example: name sort: type: string description: Sort direction. enum: - asc - desc example: asc UserGridState: type: object description: Persisted UI state for the (user, view) pair. Treated as opaque by the backend. properties: columnWidths: type: object additionalProperties: type: integer format: int32 description: Per-column widths, keyed by `field`. hiddenColumns: type: array description: Fields the user hid. items: type: string pinnedColumns: $ref: '#/components/schemas/PinnedColumns' description: Frozen columns by side. filterModel: type: object additionalProperties: {} description: AG Grid filter model. OPAQUE; the backend never interprets it. filterMode: type: string description: Filter UI mode chosen by the user. enum: - column - advanced sortModel: type: array description: User-applied sort. items: $ref: '#/components/schemas/SortModel' columnOrder: type: array description: User-applied column order (list of `field`s). items: type: string savedAt: type: string description: ISO-8601 timestamp written by the backend when the state was persisted. AssociatedAccountsDocument: type: object description: Ledger account mapping for a VAT type and company. properties: id: type: integer format: int64 description: Primary key example: 33 readOnly: true companyId: type: integer format: int64 description: Company ID for this ledger mapping. Must match the company of both incomeAccountId and expenseAccountId when those accounts are supplied. example: 1 companyName: type: string description: Company name readOnly: true incomeAccountId: type: integer format: int64 description: The unique identifier of the income ledger account. example: 10045 incomeAccountName: type: string description: The official name of the income account as registered in the chart of accounts. example: Sales Income expenseAccountId: type: integer format: int64 description: The unique identifier of the expense ledger account. example: 20067 expenseAccountName: type: string description: The official name of the expense account as registered in the chart of accounts. example: Operating Expenses VatTypeDocument: type: object description: 'VAT type (TipoIVA): tax rates, ledger mappings and reporting behaviour for a company.' properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoIVA is not versioned; always omitted) readOnly: true name: type: string description: Display name example: IVA General 21% description: type: string description: Description label: type: string description: UI / print label (etiqueta) example: IVA general 21 % enabled: type: boolean description: Whether the VAT type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true vatRate: type: number description: VAT percentage for sales example: 21 vatRatePurchase: type: number description: VAT percentage for purchases (only when differentPurchaseSaleVat is true) example: 21 differentPurchaseSaleVat: type: boolean description: Whether purchase VAT differs from sales VAT example: false vatCategory: type: string description: 'VAT category (TipoIVAEnum name: GENERAL, REDUCIDO, SUPERREDUCIDO, EXENTO, ÔǪ)' example: GENERAL nature303: type: string description: Nature for form 303 (NaturalezaIVA303 enum name) example: OPERACIONES_INTERIORES warehouseOverrides: type: array description: Per-warehouse VAT overrides (Sucursal scope) items: $ref: '#/components/schemas/VatTypeWarehouseDocument' associatedAccounts: type: array description: Ledger account mappings per company items: $ref: '#/components/schemas/AssociatedAccountsDocument' exemptionType: type: string description: Verifactu exempt operation type (OperacionExentaType name); null when not exempt example: E1 blockType: type: string description: System block marker (TipoBloqueo name, e.g. B_SII, B_SYNC); null means no block example: B_SYNC surchargeTypeId: type: integer format: int64 description: Equivalence surcharge type (TipoRE) ID example: 3 surchargeTypeName: type: string description: Equivalence surcharge type name readOnly: true excludeFromLedger: type: boolean description: Excluded from the VAT record book (libro registro) example: false commonVat: type: boolean description: Common-use VAT (IVA de uso com├║n) example: false excluded: type: boolean description: Excluded from normal selection example: false createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true VatTypeWarehouseDocument: type: object description: Warehouse-specific VAT rate override for a VAT type. properties: id: type: integer format: int64 description: Override row primary key readOnly: true warehouseId: type: integer format: int64 description: Warehouse ID (Sucursal) example: 1 warehouseName: type: string description: Warehouse name readOnly: true vatRate: type: number description: Sales VAT percentage at this warehouse (ptoIVA) example: 21 vatRatePurchase: type: number description: Purchase VAT percentage (only when differentPurchaseSaleVat is true) example: 10 differentPurchaseSaleVat: type: boolean description: Whether purchase VAT differs from sales VAT at this warehouse example: false useVatPriceAsNetPrice: type: boolean description: Treat VAT-inclusive price as net-of-VAT for purchases example: false UserBusinessContextOption: type: object description: Selectable business-context option (company or warehouse). properties: id: type: integer format: int64 description: Legacy identifier of the selectable option. example: 1 label: type: string description: Human-readable label rendered by the SPA. example: Sucursal 1 required: - id - label UserBusinessContextPreferences: type: object description: Available business-context options and the user's effective default selection. properties: companies: type: array description: Companies the user can operate on. items: $ref: '#/components/schemas/UserBusinessContextOption' warehouses: type: array description: Warehouses / branches (legacy sucursales) the user can operate on. items: $ref: '#/components/schemas/UserBusinessContextOption' currentCompanyId: type: integer format: int64 description: Current company id, derived from `currentWarehouseId`. example: 1 currentWarehouseId: type: integer format: int64 description: Current/default warehouse id (`core_usuario.sucursal_actual`). example: 1 UserPreferencesDocument: type: object description: User preferences ÔÇö unified read/write document. properties: userId: type: integer format: int64 description: Identifier of the user these preferences belong to. readOnly: true username: type: string description: Username (display + audit). readOnly: true viewTemplates: type: array description: Default plantilla per featureType. On write, replaces the per-feature template selection in full. items: $ref: '#/components/schemas/UserViewTemplateRef' screenTemplates: type: array description: Active screen template (ScreenSpec) per screenKey. On write, replaces the per-screen selection in full (analogous to viewTemplates). items: $ref: '#/components/schemas/UserScreenTemplateRef' expandedListings: type: array description: TipoDocumentoGlobal names of the listings the user keeps expanded by default. On write, replaces the set in full. items: type: string defaultDashboardId: type: integer format: int64 description: Default dashboard id. Send -1 to clear. businessContext: $ref: '#/components/schemas/UserBusinessContextPreferences' description: Available companies/warehouses and the user's effective operational context. On write, only currentWarehouseId is persisted; the current company is derived from the warehouse. UserScreenTemplateRef: type: object description: 'Pair (screenKey, templateId): the user''s active screen template for a screen.' properties: screenKey: type: string description: featureType of the screen. example: stock templateId: type: integer format: int64 description: Identifier of the persisted screen template (screen_plantilla.id) the user has selected for the screen. example: 1042 UserViewTemplateRef: type: object description: 'Pair (featureType, viewId): the user''s chosen view for a grid feature.' properties: featureType: type: string description: Canonical featureType (kebab-plural English) of the grid. example: brands viewId: type: integer format: int64 description: Identifier of the persisted view (saved column layout) the user has selected for the feature. example: 42 SolutionActionDocument: type: object description: Executable action associated with a claim solution configuration. properties: id: type: integer format: int64 description: Surrogate key for the action (not persisted in legacy schema) readOnly: true actionType: type: string description: Action category. Legacy booleans map to the codes exposed by the static catalog {@code GET /api/v2/catalogs/actionType}. enum: - REFUND - CREDIT_NOTE - WARRANTY - ORDER - LENS_CHANGE - PIN - ORDER_EDIT example: REFUND label: type: string description: Human-readable label shown in the solution card or form example: Refund notes: type: string description: Optional free-text notes or instructions for executing this action SolutionDocument: type: object description: Claim solution configuration nested under a claim type (ReclamoTipoReclamoSolucion). Write via {@link ClaimTypeDocument#getSolutions()}. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (ReclamoTipoReclamoSolucion is not versioned ÔÇö always null) readOnly: true claimTypeId: type: integer format: int64 description: Claim type this solution applies to ({@code tipo_reclamo_id}). Omit when nested in {@link ClaimTypeDocument}; the server assigns it from the parent. Present on read. example: 7 readOnly: true claimTypeName: type: string description: Claim type display name example: Defective lens readOnly: true solutionTypeId: type: integer format: int64 description: 'Solution type catalog entry ({@code tipo_solucion_id}). Selecting it copies the catalog name into {@link #title}.' example: 3 solutionTypeName: type: string description: Solution type display name ({@code ges_reclamo_tipo_solucion.nombre}) example: Replacement readOnly: true title: type: string description: Short descriptive title ({@code nombre}). Usually mirrors the solution type name. example: Replacement description: type: string description: Full textual description ({@code descripcion}) enabled: type: boolean description: Whether the solution is enabled ({@code HABILITADO}) example: true draft: type: boolean description: Draft flag ({@code BORRADOR}). When true the row is a work-in-progress draft. example: false employeeLevel: type: integer format: int32 description: Minimum employee level required to apply this solution (0ÔÇô3, {@code nivel_empleado}) example: 1 allowsLensChange: type: boolean description: Allows lens change / HC rectification ({@code permite_HC}) example: false allowsRefund: type: boolean description: Allows refund ({@code permite_reembolso}) example: true allowsPin: type: boolean description: Allows PIN payment ({@code permite_pin}) example: false allowsCreditNote: type: boolean description: Allows credit note ({@code permite_N_credito}) example: false allowsWarranty: type: boolean description: Allows warranty flow ({@code permite_garantia}) example: false allowsOrder: type: boolean description: Allows corrective order creation ({@code permite_orden}) example: true allowsOrderEdit: type: boolean description: Allows editing the linked order ({@code permite_editar_pedido}) example: false orderTypeId: type: integer format: int64 description: Order document type when {@code allowsOrder=true} ({@code tipo_orden_id}, restricted to PED_REC in legacy UI) example: 12 orderTypeName: type: string description: Order document type display name example: Corrective order readOnly: true actions: type: array default: [] description: Structured actions derived from permission flags. Legacy persistence uses boolean columns; this array is optional on write. items: $ref: '#/components/schemas/SolutionActionDocument' companyId: type: integer format: int64 description: Company ID ({@code empresa_id}). Omit when nested in {@link ClaimTypeDocument}; inherited from the parent claim type. example: 1 readOnly: true companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record ({@code CREATED_BY}) readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset, {@code CREATION_DATE}) readOnly: true lastModifiedBy: type: string description: Last user that modified the record ({@code LAST_UPDATED_BY}) readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset, {@code LAST_UPDATED_DATE}) readOnly: true SolutionTypeDocument: type: object description: Claim solution type (ReclamoTipoSolucion) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true code: type: integer format: int64 description: Business code (unique, company-scoped). Optional on create ÔÇö the WAR assigns the next sequential value when omitted. Pre-filled by `POST /solution-types/new`. example: 1001 name: type: string description: Display name example: Replacement description: type: string description: Description enabled: type: boolean description: Whether the solution type is enabled (defaults to true on create) example: true warranty: type: boolean description: Whether this solution type implies warranty coverage example: false sendEmail: type: boolean description: Whether an email notification is sent when this solution type is used example: false companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true warehouseId: type: integer format: int64 description: Destination warehouse/branch ID for shipping (sucursal env├¡o) example: 3 warehouseName: type: string description: Destination warehouse/branch name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true SeriesDocument: type: object description: Document numbering series ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (Serie is not versioned ÔÇö always null) readOnly: true series: type: string description: Series prefix / code (unique per documentKind and company) example: A documentKind: type: string description: Document family code (e.g. FAC-EMI, ALB-RECI, CLI). Immutable after create. example: FAC-EMI description: type: string description: Description enabled: type: boolean description: Whether the series is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true establishmentCode: type: string description: Establishment code (Ecuador SRI) example: '001' emissionPointCode: type: string description: Emission point code (Ecuador SRI) example: '001' authorizationCode: type: string description: Electronic invoice authorization code (Ecuador SRI) createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true ServiceLocationDocument: type: object description: Service location (branch booking profile) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key (Sucursal id) readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Albrook Mall slug: type: string description: Public booking slug example: albrook-mall address: type: string description: Postal / street address phone: type: string description: Contact phone locationType: type: string description: Location type enum: - offline - ask_booker example: offline isActive: type: boolean description: Whether the location accepts online booking (defaults to true) isPrivate: type: boolean description: Whether the location is hidden from the public booking page companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ServiceCategoryDocument: type: object description: Service category ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Examen visual description: type: string description: Description slug: type: string description: URL slug example: examen-visual sortOrder: type: integer format: int32 description: Display order (ascending) example: 10 isActive: type: boolean description: Whether the category is active (defaults to true) color: type: string description: UI color enum: - BLUE - GREEN - RED - PURPLE - ORANGE - YELLOW - GREY - BLACK example: BLUE companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true serviceIds: type: array description: Linked service IDs. On write, the full list replaces the current one. items: type: integer format: int64 createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ServiceAddOnDocument: type: object description: Service add-on (extra duration/price). properties: id: type: integer format: int64 description: Primary key readOnly: true name: type: string description: Display name example: Retinograf├¡a slug: type: string description: URL slug description: type: string description: Description duration: type: integer format: int32 description: Extra duration value example: 10 durationUnit: type: string description: Duration unit enum: - mins - hours example: mins price: type: number description: Add-on price isActive: type: boolean description: Whether the add-on is active (defaults to true) ServiceDocument: type: object description: Bookable service ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Optometr├¡a completa slug: type: string description: URL slug example: optometria-completa description: type: string description: Description serviceCategoryId: type: integer format: int64 description: Service category (TipoCita) ID serviceCategoryName: type: string description: Service category name readOnly: true staff: type: array description: Staff employee IDs that can deliver this service. At least one required. items: type: integer format: int64 serviceDuration: type: integer format: int32 description: Service duration value example: 30 serviceDurationUnit: type: string description: Duration unit enum: - mins - hours example: mins preBuffer: type: integer format: int32 description: Pre-buffer value preBufferUnit: type: string description: Pre-buffer unit enum: - mins - hours postBuffer: type: integer format: int32 description: Post-buffer value postBufferUnit: type: string description: Post-buffer unit enum: - mins - hours payment: $ref: '#/components/schemas/ServicePaymentDocument' description: Payment (amount / deposit) eventColor: type: string description: Calendar event color example: '#3B82F6' coverImage: type: string description: Cover image URL isPrivate: type: boolean description: Hidden from the public booking page formId: type: string description: External form id isActive: type: boolean description: Whether the service is enabled (defaults to true) companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true variations: type: array description: Variations (duration/payment overrides). Full replace on write. items: $ref: '#/components/schemas/ServiceVariationDocument' addOns: type: array description: Add-ons. Full replace on write. items: $ref: '#/components/schemas/ServiceAddOnDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ServicePaymentDocument: type: object description: Service payment (amount / deposit). properties: amount: type: number description: Full price amount deposit: type: number description: Deposit value (interpreted by depositType) depositType: type: string description: How deposit is interpreted enum: - percentage - amount example: percentage ServiceVariationDocument: type: object description: Service variation with own duration/buffers/payment. properties: id: type: integer format: int64 description: Primary key readOnly: true name: type: string description: Display name example: Express 20 min slug: type: string description: URL slug serviceDuration: type: integer format: int32 description: Duration value example: 20 serviceDurationUnit: type: string description: Duration unit enum: - mins - hours example: mins preBuffer: type: integer format: int32 description: Pre-buffer value preBufferUnit: type: string description: Pre-buffer unit enum: - mins - hours postBuffer: type: integer format: int32 description: Post-buffer value postBufferUnit: type: string description: Post-buffer unit enum: - mins - hours payment: $ref: '#/components/schemas/ServicePaymentDocument' description: Payment override for this variation isActive: type: boolean description: Whether the variation is active (defaults to true) ServiceBookingAddOnDocument: type: object description: Add-on selection on a booking service line. properties: id: type: integer format: int64 description: Add-on ID example: 3 quantity: type: integer format: int32 description: Quantity example: 1 duration: type: integer format: int32 description: Duration override in minutes example: 10 ServiceBookingDocument: type: object description: Multi-service booking ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Booking primary key (Evento id) readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true contactId: type: integer format: int64 description: Contact / counterparty (Tercero) ID example: 100 contactName: type: string description: Contact name readOnly: true startTime: type: string description: Start timestamp (ISO 8601 with offset) example: '2026-07-28T10:00:00+02:00' endTime: type: string description: End timestamp (ISO 8601 with offset) example: '2026-07-28T10:45:00+02:00' timezone: type: string description: IANA timezone for the booking example: Europe/Madrid serviceLocationId: type: integer format: int64 description: Service location (Sucursal) ID. Defaults to the branch default when omitted. serviceLocationName: type: string description: Service location name readOnly: true meetingLocation: type: string description: Meeting location when locationType is ask_booker calendarId: type: integer format: int64 description: Calendar ID. Defaults from the location's default calendar when omitted. title: type: string description: Title / summary notes: type: string description: Notes services: type: array description: Ordered service lines (at least one) items: $ref: '#/components/schemas/ServiceBookingLineDocument' companyId: type: integer format: int64 description: Owning company ID readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ServiceBookingLineDocument: type: object description: Service line of a multi-service booking. properties: lineId: type: integer format: int64 description: Booking-line primary key readOnly: true staffId: type: integer format: int64 description: Assigned staff (Trabajador) ID example: 7 position: type: integer format: int32 description: Order of this service in the booking example: 0 addOns: type: array description: Selected add-ons for this service line items: $ref: '#/components/schemas/ServiceBookingAddOnDocument' id: type: integer format: int64 description: Service (TipoCitaServicio) ID example: 12 AppointmentDocument: type: object description: Appointment / calendar event ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Appointment primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (use in If-Match header) readOnly: true name: type: string description: Short title / summary example: Examen optom├®trico description: type: string description: Free-text description of the event notes: type: string description: Additional notes type: type: string description: Event type discriminator enum: - MEETING - OPTICS_APPOINTMENT example: OPTICS_APPOINTMENT appointmentStatus: type: string description: Appointment lifecycle status enum: - CONFIRMED - CANCELLED - SHOWED - NO_SHOWED - INVALID - NOT_CONFIRMED statusId: type: integer format: int64 description: Custom document status ID (optional) statusName: type: string description: Custom document status name readOnly: true draft: type: boolean description: Whether the event is still a draft enabled: type: boolean description: Whether the event is active (not logically deleted) readOnly: true startAt: type: string description: Start timestamp (ISO 8601 with business offset) example: '2026-04-22T09:30:00+02:00' endAt: type: string description: End timestamp (ISO 8601 with business offset) example: '2026-04-22T10:00:00+02:00' durationMinutes: type: integer format: int32 description: Computed duration in minutes (endAt - startAt) readOnly: true companyId: type: integer format: int64 description: Company ID companyName: type: string description: Company name readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID warehouseName: type: string description: Warehouse / store name readOnly: true employeeId: type: integer format: int64 description: Employee in charge employeeName: type: string description: Employee name readOnly: true counterpartyId: type: integer format: int64 description: Counterparty (Tercero) ID ÔÇö the attendee client counterpartyName: type: string description: Counterparty name readOnly: true appointmentTypeId: type: integer format: int64 description: Appointment type (TipoCita) ID appointmentTypeName: type: string description: Appointment type name readOnly: true appointmentServiceId: type: integer format: int64 description: Appointment service (TipoCitaServicio) ID appointmentServiceName: type: string description: Appointment service name readOnly: true calendarId: type: integer format: int64 description: Calendar ID this appointment is placed on calendarName: type: string description: Calendar name readOnly: true assignedEmployeeId: type: integer format: int64 description: Employee the appointment is assigned to (GHL assignedUserId). Independent of employeeId, which is the employee in charge of the record. assignedEmployeeName: type: string description: Assigned employee name readOnly: true rrule: type: string description: iCalendar RRULE for recurring appointments example: FREQ=WEEKLY;COUNT=8 meetingLocation: type: string description: Meeting location as a JSON string (GHL meetingLocationType / meetingLocationId / overrideLocationConfig) lastAction: type: string description: Last external system that mutated this record readOnly: true bookingLog: type: string description: >- Append-only booking audit trail: one line per write performed through /api/v2/scheduling/events, recording the availability decision and any ignoreDateRange / ignoreFreeSlotValidation override that was applied. readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true BlockSlotDocument: type: object description: Calendar or employee block slot ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö no OPTLOCK column) readOnly: true title: type: string description: Block title example: Formaci├│n de equipo startAt: type: string description: Block start (ISO 8601 with business offset) example: '2026-07-27T13:00:00+02:00' endAt: type: string description: Block end (ISO 8601 with business offset) example: '2026-07-27T14:00:00+02:00' calendarId: type: integer format: int64 description: Calendar blocked. Mutually exclusive with employeeId. calendarName: type: string description: Calendar name readOnly: true employeeId: type: integer format: int64 description: Employee blocked across every calendar. Mutually exclusive with calendarId. employeeName: type: string description: Employee name readOnly: true companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true CalendarDocument: type: object description: Calendar configuration (GHL-like) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö no OPTLOCK column) readOnly: true name: type: string description: Display name example: ├ôptica Central ÔÇö Cabina 1 description: type: string description: Description slug: type: string description: URL slug for the booking page widgetSlug: type: string description: Widget slug widgetType: type: string description: Widget type enum: - default - classic example: default eventTitle: type: string description: Event title template example: '{{contact.name}}' color: type: string description: Display color (hex) example: '#2f7ed8' active: type: boolean description: Whether the calendar is bookable online (GHL isActive) enabled: type: boolean description: Legacy enabled flag (habilitado); defaults to true on create groupId: type: integer format: int64 description: Calendar group id groupName: type: string description: Calendar group name readOnly: true calendarType: type: string description: GHL-like calendar type (column calendar_type) enum: - event - personal - round_robin - collective - class_booking - service_booking - branch example: branch legacyCalendarType: type: string description: Legacy JSF TipoCalendario (SERVICIO/PERSONAL) ÔÇö column tipoCalendario enum: - SERVICIO - PERSONAL eventType: type: string description: Round-robin strategy when calendarType is round_robin enum: - RoundRobin_OptimizeForAvailability - RoundRobin_OptimizeForEqualDistribution teamMembers: type: array description: Team members (replaces employeeIds on write when present). On write, the full list replaces the current assignment. items: $ref: '#/components/schemas/TeamMemberDocument' employeeIds: type: array description: Legacy flat employee ids. Used when teamMembers is null/absent. On write, the full list replaces the current one. items: type: integer format: int64 slotDuration: type: integer format: int32 description: Slot duration (GHL slotDuration) ÔÇö maps to duracionMinutos example: 30 slotDurationUnit: type: string description: Slot duration unit enum: - mins - hours example: mins defaultDurationMinutes: type: integer format: int32 description: Alias of slotDuration kept for ADR-010 clients slotMinutes: type: integer format: int32 description: Grid slot size in minutes (legacy duracionCalendario) example: 15 defaultView: type: string description: Default view enum: - DIA - SEM - MES - LISTA example: SEM timeUnit: type: string description: Legacy time unit for slot / duration enum: - MINUTES - HOURS example: MINUTES predefinedSlots: type: boolean description: Whether events must snap to predefined slots slotInterval: type: integer format: int32 description: Interval between offered slot starts example: 15 slotIntervalUnit: type: string description: Unit for slotInterval example: mins slotBuffer: type: integer format: int32 description: Post-appointment buffer example: 0 slotBufferUnit: type: string description: Unit for slotBuffer example: mins preBuffer: type: integer format: int32 description: Pre-appointment buffer example: 0 preBufferUnit: type: string description: Unit for preBuffer example: mins appoinmentPerSlot: type: integer format: int32 description: Max appointments per slot (seats for class_booking) appoinmentPerDay: type: integer format: int32 description: Max appointments per day allowBookingAfter: type: integer format: int32 description: Minimum notice before booking (allowBookingAfter) allowBookingAfterUnit: type: string description: Unit for allowBookingAfter example: hours allowBookingFor: type: integer format: int32 description: Booking horizon (allowBookingFor) allowBookingForUnit: type: string description: Unit for allowBookingFor example: days openHours: type: array description: Weekly open hours items: $ref: '#/components/schemas/OpenHoursRuleDocument' availabilities: type: array description: Date-specific availability exceptions items: $ref: '#/components/schemas/DateAvailabilityDocument' availabilityType: type: integer format: int32 description: 0 = openHours only, 1 = custom only, null = both openingTime: type: string description: Legacy opening time (HH:mm:ss) ÔÇö prefer openHours example: '09:00:00' closingTime: type: string description: Legacy closing time (HH:mm:ss) ÔÇö prefer openHours example: '20:00:00' enableRecurring: type: boolean description: Whether recurring bookings are enabled recurring: $ref: '#/components/schemas/RecurringConfigDocument' description: Recurring configuration lookBusyConfig: $ref: '#/components/schemas/LookBusyConfigDocument' description: Look-busy configuration formId: type: string description: External form id formSubmitType: type: string description: Form submit behaviour enum: - RedirectURL - ThankYouMessage formSubmitRedirectUrl: type: string description: Redirect URL after form submit formSubmitThanksMessage: type: string description: Thank-you message after form submit autoConfirm: type: boolean description: Auto-confirm new appointments allowReschedule: type: boolean description: Allow reschedule from the booking page allowCancellation: type: boolean description: Allow cancellation from the booking page companyId: type: integer format: int64 description: Company ID companyName: type: string description: Company name readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID (required for calendarType=branch) warehouseName: type: string description: Warehouse / store name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true DateAvailabilityDocument: type: object description: Custom availability for a concrete calendar date. properties: date: type: string description: Calendar date (YYYY-MM-DD) example: '2026-08-15' hours: type: array description: Hour ranges for that date items: $ref: '#/components/schemas/OpenHourSlotDocument' deleted: type: boolean description: Soft-deleted flag from GHL payloads LocationConfigurationDocument: type: object description: Meeting location configuration for a calendar team member. properties: kind: type: string description: Location kind enum: - custom - zoom_conference - google_conference - inbound_call - outbound_call - physical - booker - ms_teams_conference example: physical location: type: string description: Free-text location / address / dial-in meetingId: type: string description: External meeting id when applicable alias: type: string description: Display alias position: type: integer format: int32 description: Sort position zoomOauthId: type: string description: Zoom OAuth connection id when kind is zoom_conference LookBusyConfigDocument: type: object description: 'Look-busy filter: hide a percentage of free slots.' properties: enabled: type: boolean description: Whether look-busy is enabled LookBusyPercentage: type: integer format: int32 description: Percentage of free slots to hide (0-100) example: 30 OpenHourSlotDocument: type: object description: Open/close hour-minute pair for a weekly openHours rule. properties: openHour: type: integer format: int32 description: Open hour (0-23) example: 9 openMinute: type: integer format: int32 description: Open minute (0-59) example: 0 closeHour: type: integer format: int32 description: Close hour (0-23) example: 18 closeMinute: type: integer format: int32 description: Close minute (0-59) example: 0 OpenHoursRuleDocument: type: object description: Weekly open-hours rule (days of week + hour ranges). properties: daysOfTheWeek: type: array description: Days of the week as integers (0=Sunday ÔǪ 6=Saturday, GHL convention) example: - 1 - 2 - 3 - 4 - 5 items: type: integer format: int32 hours: type: array description: Hour ranges for the selected days items: $ref: '#/components/schemas/OpenHourSlotDocument' RecurringConfigDocument: type: object description: Recurring appointment configuration for a calendar. properties: freq: type: string description: Frequency enum: - DAILY - WEEKLY - MONTHLY example: WEEKLY count: type: integer format: int32 description: Number of occurrences (max 24) example: 4 bookingOption: type: string description: What to do when a slot is busy enum: - skip - continue - book_next bookingOverlapDefaultStatus: type: string description: Default status when booking overlaps enum: - confirmed - new TeamMemberDocument: type: object description: Calendar team member (staff assigned to a calendar). properties: employeeId: type: integer format: int64 description: Employee (trabajador) id ÔÇö GHL userId equivalent example: 42 employeeName: type: string description: Employee display name readOnly: true priority: type: number format: double description: 'GHL priority: 0 (low), 0.5 (medium) or 1 (high)' example: 0.5 isPrimary: type: boolean description: Primary member (mandatory and unique on collective calendars) locationConfigurations: type: array description: Meeting location configurations for this member items: $ref: '#/components/schemas/LocationConfigurationDocument' ScheduleIntervalDocument: type: object description: Schedule interval (HH:MM from/to). properties: from: type: string description: Start time (HH:MM) example: '09:00' to: type: string description: End time (HH:MM) example: '17:00' ScheduleRuleDocument: type: object description: Worker schedule rule (weekday or date override). properties: type: type: string description: Rule type enum: - wday - date example: wday day: type: string description: Weekday when type is wday enum: - monday - tuesday - wednesday - thursday - friday - saturday - sunday example: monday date: type: string description: Calendar date when type is date (YYYY-MM-DD) example: '2026-07-26' intervals: type: array description: Open intervals for this rule items: $ref: '#/components/schemas/ScheduleIntervalDocument' StaffScheduleDocument: type: object description: Staff / worker schedule ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Horario semanal ÔÇö Juan active: type: boolean description: Whether the schedule is active (defaults to true on create) employeeId: type: integer format: int64 description: Employee (trabajador) ID employeeName: type: string description: Employee display name readOnly: true timeZone: type: string description: IANA timezone example: Europe/Madrid calendarIds: type: array description: Linked calendar IDs items: type: integer format: int64 rules: type: array description: Weekly / date override rules items: $ref: '#/components/schemas/ScheduleRuleDocument' CalendarResourceDocument: type: object description: Calendar resource (room or equipment) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Cabina 1 description: type: string description: Description resourceType: type: string description: Resource family enum: - ROOM - EQUIPMENT example: ROOM quantity: type: integer format: int32 description: Available quantity (defaults to 1 on create) capacity: type: integer format: int32 description: Capacity per unit outOfService: type: boolean description: Whether the resource is out of service (defaults to false on create) calendarIds: type: array description: Linked calendar IDs items: type: integer format: int64 companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true CalendarGroupDocument: type: object description: Calendar group ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Cabinas ├│ptica description: type: string description: Description slug: type: string description: URL slug example: cabinas-optica active: type: boolean description: Whether the group is active (defaults to true on create) companyId: type: integer format: int64 description: Owning company ID companyName: type: string description: Owning company name readOnly: true AppointmentNoteDocument: type: object description: Note attached to an appointment ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö no OPTLOCK column) readOnly: true appointmentId: type: integer format: int64 description: Owning appointment ID. Taken from the path on write. readOnly: true body: type: string description: Note text example: El paciente avisa de que llegar├í 10 minutos tarde. employeeId: type: integer format: int64 description: Employee that owns the note (GHL userId equivalent) employeeName: type: string description: Employee name readOnly: true companyId: type: integer format: int64 description: Owning company ID readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true AddressDto: type: object description: Postal / physical address properties: country: type: string description: ISO 3166-1 country code or name example: ES province: type: string description: Province or state example: Madrid municipality: type: string description: Municipality example: Alcobendas locality: type: string description: City / locality example: Madrid postalCode: type: string description: Postal / ZIP code example: '28100' streetType: type: string description: Street type (Calle, Avenida, ÔǪ) example: Calle streetName: type: string description: Street name example: Gran V├¡a streetNumber: type: string description: Street number example: '42' apartment: type: string description: Apartment / floor / door example: 3┬║A AppliedPriceRuleDocument: type: object description: 'Pricing rule the backend applied to this line (tariff discount, combo or PIN). Read-only: eligibility is resolved server-side; opt out via excludedTariffIds/excludePin.' properties: id: type: integer format: int64 description: Applied rule record ID ruleType: type: string description: Rule type enum: - DISCOUNT - COMBO - PIN example: COMBO tariffId: type: integer format: int64 description: Tariff ID that produced the discount tariffName: type: string description: Tariff name comboId: type: integer format: int64 description: Combo ID when the rule is a combo comboName: type: string description: Combo name purchaseCondition: type: boolean description: True when this line is the PURCHASE CONDITION of the combo (carries discount 0 and locks quantity edition) purchaseConditionId: type: integer format: int64 description: Combo purchase-condition ID discountConditionId: type: integer format: int64 description: Combo discount-condition ID discountValue: type: number description: Discount value the rule resolved categoryIds: type: array description: Product category IDs the rule is restricted to items: type: integer format: int64 readOnly: true AttachmentRef: type: object description: Reference to a file attachment linked to a document properties: id: type: integer format: int64 description: Attachment ID example: 501 fileName: type: string description: Original file name example: factura_scan.pdf mimeType: type: string description: MIME type example: application/pdf sizeBytes: type: integer format: int64 description: File size in bytes example: 245760 downloadUrl: type: string description: URL to download the attachment LineDiscountDocument: type: object description: >- Line discount element (insurer contribution, discount PIN, points redemption). On writes the engine enforces per-line and per-document caps, so the resulting amounts may be lower than requested. properties: id: type: integer format: int64 description: Discount element ID readOnly: true type: type: string description: Element type enum: - INSURER - PIN - POINTS - DISCOUNT - COMBO example: INSURER mode: type: string description: 'How the element is expressed on input: PCT (percentage over the line commercial net) or AMOUNT (fixed amount). POINTS amounts are tax-included; PIN and INSURER amounts are tax-excluded.' enum: - PCT - AMOUNT example: PCT pct: type: number description: Percentage over the line commercial net (mode PCT) example: 50 amount: type: number description: Discount amount WITHOUT tax (input for mode AMOUNT on INSURER/PIN; output = actually applied after caps) example: 20 amountTaxIncluded: type: number description: Discount amount WITH tax (input for POINTS; output = actually applied after caps) example: 24.2 capTaxIncluded: type: number description: Per-line cap, tax included (insurer condition max) example: 30 insurerId: type: integer format: int64 description: Insurer (counterparty) ID ÔÇö required for type INSURER example: 77 insurerName: type: string description: Insurer name readOnly: true accountId: type: integer format: int64 description: Ledger account ID the discount posts to readOnly: true required: - type PaymentDocument: type: object description: Payment (cobro) ÔÇö unified read/write document. READ_ONLY fields are populated by the server on responses and ignored if sent by the client (so GET ÔåÆ mutate ÔåÆ PUT round-trips never fail). properties: id: type: integer format: int64 description: Payment primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version. Cobro has no OPTLOCK column, so this field is always null. readOnly: true series: type: string description: Payment series prefix readOnly: true number: type: integer format: int64 description: Sequential payment number readOnly: true code: type: string description: Full payment code (series + number) readOnly: true transactionId: type: string description: External transaction ID provided by the payment processor / TPV readOnly: true externalRef: type: string description: External reference (POS receipt id, bank statement reference, ...) readOnly: true uuid: type: string description: Universal unique identifier (used by Verifactu / electronic invoicing flows) readOnly: true transactionKind: type: string description: Accounting transaction kind. Defaults to CP (regular customer/supplier settlement). enum: - CP - RI - C - MC example: CP lifecycleStatus: type: string description: Regulatory lifecycle status of the payment (e.g. VI=open, AN=cancelled, ...) readOnly: true issued: type: boolean description: true = sales-side payment (against an issued document); false = purchase-side payment (against a received document). readOnly: true closed: type: boolean description: Whether the payment has been closed (no further changes allowed) readOnly: true validated: type: boolean description: Whether the payment has been validated by an authorised user readOnly: true amount: type: number description: Payment amount. Negative values are legal for refunds and voucher-generating payments (credit notes); sign coherence with the parent document total is enforced server-side. example: 150 amountTendered: type: number description: Amount physically tendered by the customer (cash scenarios) example: 200 minimum: 0 changeGiven: type: number description: Change given back (cash scenarios) readOnly: true amountSystem: type: number description: Amount in system currency readOnly: true exchangeRate: type: number description: Exchange rate to system currency example: 1 maximum: 100000 minimum: 0.000001 currencyCode: type: string description: ISO 4217 currency code example: EUR maxLength: 3 minLength: 3 currencyCodeSystem: type: string description: System currency code readOnly: true paymentDate: type: string description: Payment date (ISO 8601 with business timezone offset; defaults to today on create if omitted) example: '2026-03-15T10:30:00+01:00' dueDate: type: string description: Due date for deferred payments (ISO 8601 with business timezone offset) withdrawalDate: type: string description: Withdrawal date (when the payment was actually pulled from the cash register) readOnly: true accountingDate: type: string description: Accounting date (when the journal entry hits the books) readOnly: true counterpartyId: type: integer format: int64 description: Customer or supplier ID counterpartyName: type: string description: Customer or supplier name readOnly: true agreementCounterpartyId: type: integer format: int64 description: Agreement counterparty ID readOnly: true agreementCounterpartyName: type: string description: Agreement counterparty name readOnly: true paymentMethodId: type: integer format: int64 description: Payment method ID (forma de pago) example: 1 paymentMethodName: type: string description: Payment method name readOnly: true paymentAccountId: type: integer format: int64 description: Payment account ID (bank account, cash registerÔǪ) paymentAccountName: type: string description: Payment account name readOnly: true counterpartyAccountId: type: integer format: int64 description: Counterparty bank account ID counterpartyAccountName: type: string description: Counterparty bank account name readOnly: true invoiceId: type: integer format: int64 description: Linked invoice ID (sales or purchase) deliveryNoteId: type: integer format: int64 description: Linked delivery note ID (sales or purchase) orderId: type: integer format: int64 description: Linked order ID (sales or purchase) quoteId: type: integer format: int64 description: Linked sales-quote ID (deposits / prepayments) installmentId: type: integer format: int64 description: Installment ID this payment settles discountVoucherId: type: integer format: int64 description: Loyalty discount voucher (PIN) applied to this payment claimId: type: integer format: int64 description: Related claim / refund process ID readOnly: true cashRegisterId: type: integer format: int64 description: Cash register withdrawal record ID readOnly: true journalEntryId: type: integer format: int64 description: Journal entry ID (asiento) created for this payment readOnly: true voucherJournalEntryId: type: integer format: int64 description: Voucher journal entry ID (asiento de vale) readOnly: true accountingLedgerNumber: type: integer format: int32 description: Accounting ledger number (1..N) readOnly: true linkedToAccounting: type: boolean description: Whether the payment is linked to accounting (vinculado) cardPosPayment: type: boolean description: Whether the payment was made via a TPV / POS terminal readOnly: true cardPosActive: type: boolean description: Whether the POS integration is currently active for this payment readOnly: true cardPosType: type: string description: POS terminal type readOnly: true cardType: type: string description: Card type (DEBIT, CREDIT) example: CREDIT cardTypeId: type: integer format: int64 description: Card type ID cardTypeName: type: string description: Card type name readOnly: true cardAcquirerNetwork: type: string description: Card acquirer network (the merchant bank network) readOnly: true cardAcquirerName: type: string description: Card acquirer name readOnly: true cardGroupName: type: string description: Card group name (Visa group, Mastercard group, ...) readOnly: true cardholderName: type: string description: Cardholder name readOnly: true cardMaskedNumber: type: string description: Card masked number (only the last digits are kept) readOnly: true cardExpiryDate: type: string description: Card expiry date (ISO 8601 date-only) example: '2027-12-31' readOnly: true cardAuthorizationCode: type: string description: Card authorization code returned by the acquirer readOnly: true cardReferenceNumber: type: integer format: int64 description: Card transaction reference number (acquirer-side) readOnly: true cardBatch: type: string description: Card batch number (lote) readOnly: true cardPaymentDate: type: string description: Card payment timestamp (ISO 8601 with business timezone offset) readOnly: true cardTerminalId: type: string description: Card terminal ID (TID) readOnly: true cardMerchantId: type: string description: Card merchant ID (MID) readOnly: true cardReadMode: type: string description: Card read mode (CHIP, CONTACTLESS, MANUAL, ...) readOnly: true cardOttCode: type: string description: PayClub OTT code (when applicable) readOnly: true cardPayClub: type: boolean description: Whether this payment used PayClub readOnly: true cardCreditType: type: string description: Card credit type (CORRIENTE, DIFERIDO, ANULACION, REVERSO, PAYCLUB, ...) readOnly: true cardDeferredCode: type: integer format: int32 description: Deferred payment plan code cardDeferredTerm: type: integer format: int32 description: Deferred payment term in months example: 12 minimum: 0 cardGracePeriodMonths: type: integer format: int32 description: Grace period in months example: 3 minimum: 0 cardInterestAmount: type: number description: Interest amount accrued for deferred payments readOnly: true paymentMethodTaxPct: type: number description: Tax on payment method percentage (used for foreign-currency surcharges) readOnly: true paymentMethodTaxAmount: type: number description: Tax on payment method amount readOnly: true zeroRatedTaxBase: type: number description: Zero-rated tax base (e.g. exempt operations under Mexican fiscal law) readOnly: true taxableBase: type: number description: Taxable base (base imponible) for the VAT applied directly on the payment readOnly: true vatAmount: type: number description: VAT amount applied directly on the payment readOnly: true cancelledPaymentId: type: integer format: int64 description: ID of the payment that THIS payment cancels (anulaci├│n) readOnly: true substitutePaymentId: type: integer format: int64 description: ID of the payment that substitutes THIS one readOnly: true previousOutstandingAmount: type: number description: Outstanding amount of the document BEFORE this payment was registered readOnly: true outstandingAmount: type: number description: Outstanding amount of the document AFTER this payment was registered readOnly: true partialPaymentSequence: type: integer format: int32 description: Sequence index of this payment within a partial-payment series (used by Mexican CFDI complemento de pagos) readOnly: true companyId: type: integer format: int64 description: Issuing company ID readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID where the payment is registered sourceSystem: type: string description: Source system (system that originally created this payment) readOnly: true sapCode: type: string description: SAP code readOnly: true lockType: type: string description: Lock type readOnly: true description: type: string description: Short description (cash-withdrawal label in register closes) example: Dep├│sito banco maxLength: 4000 minLength: 0 attachmentId: type: integer format: int64 description: Attachment ID linked to this payment readOnly: true attachment: $ref: '#/components/schemas/AttachmentRef' description: Attachment metadata. For cash-close withdrawals the view-service enriches {@code downloadUrl} on GET. readOnly: true notes: type: string description: Free-text notes example: Paid via bank transfer maxLength: 4000 minLength: 0 createdBy: type: string description: Created by readOnly: true createdAt: type: string description: Created at (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true lastModifiedBy: type: string description: Last modified by readOnly: true lastModifiedAt: type: string description: Last modified at (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true required: - amount RelatedDocumentRef: type: object description: >- Reference to a related document. The other side of a ges_relacion_documento (header) or ges_relacion_linea (line) row, carrying enough metadata to identify the related document without an extra round-trip. properties: id: type: integer format: int64 description: Primary key of the relation row itself (ges_relacion_documento.id or ges_relacion_linea.id), NOT the id of the related document. Use relatedDocumentId for that. example: 1842 relatedDocumentId: type: integer format: int64 description: >- ID of the document on the OTHER side of the relation, when the relation is stored at document-header level. Line-level relations link line rows and may omit this field. Combined with relatedDocumentType is enough to fetch the related document via GET /api/v2/{resource}/{id}. example: 320 relatedDocumentType: type: string description: >- Canonical type of the document on the other side of the relation. Derived from relationType and which FK column carries the destination on the relation row. Aligned with the documentType discriminator used by InvoiceDocument, OrderResponse, SalesQuoteResponse, SalesDeliveryNoteResponse, OpticalOrderDocument. enum: - INVOICE - DELIVERY_NOTE - ORDER - PURCHASE_ORDER - QUOTE - INVENTORY_TRANSFER - REPAIR_ORDER - MANUFACTURING_ORDER - CLAIM - LOAD - OPTICAL_ORDER example: DELIVERY_NOTE concept: type: string description: 'Business concept of the relation (ConceptoRelacion: DELIVERY, BILLING, CANCELLATION, ...)' example: DELIVERY relationType: type: string description: >- Raw relation type code as stored in the legacy schema (TipoRelacionLinea: F_F, A_F, PRE_F, PE_F, REP_FAC, ...). relatedDocumentType is the derived public counterpart; this field is exposed for clients that need round-trip fidelity with the legacy domain model. example: A_F quantity: type: number description: Quantity transferred between the two documents (units traced from origin to destination). example: 5 documentDate: type: string description: Document date of the relation row (ges_relacion_documento.fechaDocumento). Header-level relations only. ISO 8601 with business timezone offset. example: '2026-03-15T10:30:00+01:00' manual: type: boolean description: Whether the relation was created manually by a user vs automatically by the system. Header-level relations only. externalDocumentNumber: type: string description: External document number of the related document, when the relation captures it (e.g. SII Chile DTE folio in nroFolio). Header-level relations only. example: '0000001234' SalesQuoteDocument: type: object description: Sales quote ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Document primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (use in If-Match header) readOnly: true documentType: type: string description: Document type discriminator enum: - INVOICE - ORDER - DELIVERY_NOTE - QUOTE readOnly: true series: type: string description: Document series prefix example: A maxLength: 70 minLength: 0 number: type: integer format: int64 description: Sequential document number (server-assigned) example: 1234 readOnly: true code: type: string description: Full document code (series + number) example: A-1234 readOnly: true deliveryStatus: type: string description: Delivery status (P=not delivered, EP=partial, E=delivered) enum: - P - EP - E readOnly: true lifecycleStatus: type: string description: Regulatory lifecycle status readOnly: true paymentStatus: type: string description: Computed payment status enum: - UNPAID - PARTIAL - PAID - OVERPAID readOnly: true documentStatusId: type: integer format: int64 description: User-defined document status ID (Kanban) documentStatusName: type: string description: User-defined document status name readOnly: true issued: type: boolean description: true = outgoing (sales side), false = incoming (purchase side) draft: type: boolean description: Whether the document is still a draft readOnly: true enabled: type: boolean description: Whether the document is active (not logically deleted) readOnly: true verified: type: boolean description: Whether the document has been verified readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset; defaults to today on create if omitted) example: '2026-03-15T10:30:00+01:00' shippingDate: type: string description: Shipping / delivery date (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true counterpartyId: type: integer format: int64 description: Customer or supplier ID (required on create) example: 42 counterpartyName: type: string description: Customer or supplier name readOnly: true counterpartyTaxId: type: string description: Customer or supplier tax ID (NIF/CIF) readOnly: true agreementCounterpartyId: type: integer format: int64 description: Agreement counterparty ID (B2B convention party, e.g. mutual insurer) agreementCounterpartyName: type: string description: Agreement counterparty name readOnly: true companyId: type: integer format: int64 description: Issuing company ID example: 1 companyName: type: string description: Issuing company name readOnly: true companyTaxId: type: string description: Issuing company tax ID readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID (required on create) example: 1 warehouseName: type: string description: Warehouse / store name readOnly: true shippingAddressId: type: integer format: int64 description: Shipping address ID (existing address on create) shippingAddress: $ref: '#/components/schemas/AddressDto' description: Inline shipping address (created if no ID is given on create; denormalised on response) billingAddress: $ref: '#/components/schemas/AddressDto' description: Billing address (overrides counterparty default) employeeId: type: integer format: int64 description: Sales employee ID employeeName: type: string description: Sales employee name readOnly: true optometristId: type: integer format: int64 description: Optometrist ID optometristName: type: string description: Optometrist name readOnly: true documentTypeId: type: integer format: int64 description: User-defined document type ID documentTypeName: type: string description: User-defined document type name readOnly: true paymentTermsId: type: integer format: int64 description: Payment terms ID example: 1 paymentTermsName: type: string description: Payment terms description readOnly: true basePriceListId: type: integer format: int64 description: Base price list ID basePriceListName: type: string description: Base price list name readOnly: true discountPriceListId: type: integer format: int64 description: Discount price list ID discountPriceListName: type: string description: Discount price list name readOnly: true taxBehavior: type: string description: How tax is treated on prices enum: - INCLUDED - EXCLUDED - EXEMPT example: INCLUDED withholdingTaxTypeId: type: integer format: int64 description: Withholding tax type ID withholdingTaxTypeName: type: string description: Withholding tax type name readOnly: true internalRef: type: string description: Internal reference code example: REF-INT-001 maxLength: 40 minLength: 0 externalRef: type: string description: External reference (customer PO, etc.) example: PO-2026-789 maxLength: 255 minLength: 0 notes: type: string description: Free-text notes totalQuantity: type: number description: Sum of line quantities readOnly: true grossAmount: type: number description: Gross amount before discounts readOnly: true commercialNetAmount: type: number description: Operation net amount BEFORE insurer/customer copayment split. readOnly: true discountAmount: type: number description: Total commercial discount amount readOnly: true copaymentDiscount: type: number description: Insurance copayment discount readOnly: true specialDiscountPct: type: number description: Special discount percentage readOnly: true specialDiscountAmount: type: number description: Special discount amount readOnly: true earlyPaymentDiscountPct: type: number description: Early-payment discount percentage (pronto pago) earlyPaymentDiscount: type: number description: Early-payment discount amount (pronto pago) readOnly: true netAmount: type: number description: Taxable base / net amount readOnly: true vatAmount: type: number description: Total VAT amount readOnly: true surchargeEquivalencePct: type: number description: Surcharge equivalence percentage readOnly: true surchargeEquivalenceAmount: type: number description: Surcharge equivalence amount readOnly: true withholdingTaxBase: type: number description: 'Withholding tax base. Writable: overrides the derived base when the withholding does not apply to the full net.' withholdingTaxPct: type: number description: Withholding tax percentage (IRPF). Writable. withholdingOnFullNet: type: boolean description: >- When true the withholding percentage applies over the FULL document net (legacy irpfTotalDocumento); when false it applies over withholdingTaxBase. Full-state write: null/false apply the same (percentage over withholdingTaxBase); omit the key in a merge-patch to leave it unchanged. withholdingTaxAmount: type: number description: Withholding tax amount (primary) readOnly: true shippingAmount: type: number description: Shipping cost readOnly: true financingPct: type: number description: Financing surcharge percentage readOnly: true financingAmount: type: number description: Financing surcharge amount readOnly: true paymentMethodTaxAmount: type: number description: >- Payment-tax total (IGTF): sum of the per-payment paymentMethodTaxAmount quotas accrued by foreign-currency payments. Header aggregate with its own ledger account - NEVER distributed to lines, and excluded from product-margin analytics. The customer-facing grand total is total + paymentMethodTaxAmount. readOnly: true commercialTotalAmount: type: number description: Operation total (with VAT) BEFORE insurer/customer copayment split. readOnly: true total: type: number description: Document total readOnly: true totalPaid: type: number description: Amount already paid readOnly: true outstandingAmount: type: number description: Outstanding amount (total - totalPaid) readOnly: true currencyCode: type: string description: Document currency code (ISO 4217) example: EUR maxLength: 3 minLength: 3 currencyCodeSystem: type: string description: System / home currency code readOnly: true currencyDecimals: type: integer format: int32 description: >- Decimal places used to round monetary amounts in the document currency. Derived server-side from the business rule (0 for zero-decimal currencies such as CLP/COP/XOF/GMD, 2 otherwise); feed it to the client calc-engine CalcContext instead of hardcoding a table. example: 2 readOnly: true currencyDecimalsSystem: type: integer format: int32 description: Decimal places of the system / home currency (same derivation rule as currencyDecimals) example: 2 readOnly: true exchangeRate: type: number description: Exchange rate to system currency example: 1 minimum: 0 grossAmountSystem: type: number description: Gross amount in system currency readOnly: true discountAmountSystem: type: number description: Discount amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT amount in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true roundingMode: type: string description: Rounding mode applied readOnly: true relationConcept: type: string description: Inter-document relation concept readOnly: true relationType: type: string description: Inter-document relation type readOnly: true linkableQuantity: type: number description: Quantity still available for linking readOnly: true relationQuantity: type: number description: Quantity already linked readOnly: true totalApprovals: type: integer format: int32 description: Number of required approvals readOnly: true validatedApprovals: type: integer format: int32 description: Number of validated approvals readOnly: true relatedDocuments: type: array description: Documents related to this one items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true attachments: type: array description: File attachments items: $ref: '#/components/schemas/AttachmentRef' readOnly: true createdBy: type: string description: User who created the document readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: User who last modified the document readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business timezone offset) readOnly: true sourceSystem: type: string description: System that originated this document readOnly: true sapCode: type: string description: SAP document code readOnly: true lockType: type: string description: Lock type if the document is locked readOnly: true payments: type: array description: Inline payments registered against this document. Use the standalone POST /api/v2/payments to add more after creation. items: $ref: '#/components/schemas/PaymentDocument' lines: type: array description: Sales-quote line items items: $ref: '#/components/schemas/SalesQuoteLineDocument' validUntilDate: type: string description: Quote validity end date ÔÇö after this date the offer expires (ISO 8601 date-only) example: '2026-04-30' proforma: type: boolean description: Whether this quote is a pro-forma invoice (printed as Factura Proforma). Pro-formas are NOT fiscal documents. discountVoucherId: type: integer format: int64 description: Loyalty discount voucher (PIN) ID applied to the quote discountVoucherCode: type: string description: Loyalty discount voucher (PIN) code readOnly: true autoIssueDiscountVoucher: type: boolean description: Whether a discount voucher is auto-issued when the quote is closed visitReasonId: type: integer format: int64 description: Visit reason ID (clinical context) visitReasonName: type: string description: Visit reason name readOnly: true required: - counterpartyId - warehouseId SalesQuoteLineDocument: type: object description: Sales-quote line ÔÇö read/write document. properties: id: type: integer format: int64 description: Line ID ÔÇö null on create for new lines, present to update an existing line lineNumber: type: integer format: int32 description: Sequential line number within the document readOnly: true productId: type: integer format: int64 description: Product ID (required on create) example: 1024 productName: type: string description: Line name shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived name. productDescription: type: string description: Line description shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived description. extendedDescription: type: string description: Additional line description packs: type: number description: Number of packs (unidades por pack ya resueltas) example: 2 batch: type: string description: Batch / lot text example: L-2026-03 expirationDate: type: string description: Batch expiration date (ISO 8601 date) example: '2027-06-30' unitPrice: type: number description: Unit price before discounts. Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA, WebPos Panama) are enforced server-side. example: 49.9 quantity: type: number description: >- Quantity (required on create). Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA credit notes require quantity <= -1) are enforced server-side. example: 2 grossAmount: type: number description: Gross amount (qty x price) readOnly: true discountPct: type: number description: Line discount percentage (0-100) example: 10 maximum: 100 minimum: 0 discountAmount: type: number description: Absolute discount amount (alternative to percentage) example: 5 minimum: 0 commercialNetAmount: type: number description: Line net amount BEFORE insurer/customer copayment split. readOnly: true copaymentDiscount: type: number description: Copayment discount (insurance) readOnly: true netAmount: type: number description: Taxable net amount readOnly: true vatTypeId: type: integer format: int64 description: VAT type ID example: 1 vatTypeName: type: string description: VAT type name readOnly: true vatPct: type: number description: VAT percentage readOnly: true vatAmount: type: number description: VAT amount readOnly: true manualVatAmount: type: number description: >- Manual VAT amount override. Input-only intent: when set on a write it replaces the computed line VAT (legacy 'IVA manual'); never returned by GET (read vatAmount instead), so omitting/null leaves the computed VAT untouched. writeOnly: true manualSurchargeAmount: type: number description: 'Manual surcharge amount override (legacy ''RE manual''). Input-only intent: never returned by GET (read surchargeAmount instead).' writeOnly: true surchargeTypeId: type: integer format: int64 description: Surcharge equivalence type ID surchargeTypeName: type: string description: Surcharge type name readOnly: true surchargePct: type: number description: Surcharge percentage readOnly: true surchargeAmount: type: number description: Surcharge amount readOnly: true total: type: number description: Line total (net + VAT + surcharge) readOnly: true commercialTotalAmount: type: number description: Line total (with VAT) BEFORE insurer/customer copayment split. readOnly: true discounts: type: array description: >- Line discount elements (insurer contribution, discount PIN, points redemption) applied AFTER the commercial discount. On writes: null = leave untouched; a list = reconcile (present elements are applied/updated via the pricing engine ÔÇö caps enforced ÔÇö, absent elements are removed). items: $ref: '#/components/schemas/LineDiscountDocument' appliedPriceRule: $ref: '#/components/schemas/AppliedPriceRuleDocument' description: Pricing rule the backend applied to this line (tariff discount, combo or PIN). Explains the commercial discount origin. readOnly: true excludedTariffIds: type: array description: Tariff IDs excluded from automatic pricing on this line (promotion opt-out). The sentinel -1 (exclude PIN) is managed through excludePin instead. items: type: integer format: int64 excludePin: type: boolean description: Exclude the document discount PIN from this line campaignId: type: integer format: int64 description: Campaign / promotion ID campaignName: type: string description: Campaign name readOnly: true grossAmountSystem: type: number description: Gross amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true reservedQuantity: type: number description: Reserved stock quantity readOnly: true vatAccountId: type: integer format: int64 description: VAT ledger account ID surchargeAccountId: type: integer format: int64 description: Surcharge equivalence ledger account ID revenueAccountId: type: integer format: int64 description: Revenue ledger account ID relatedDocuments: type: array description: Related documents linked to this line items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true opticalOrderId: type: integer format: int64 description: ID of the optical order (encargo) this line belongs to. readOnly: true baseType: type: string description: Base document type enum: - ORDER - DELIVERY_NOTE - INVOICE - QUOTE writeOnly: true baseEntry: type: integer format: int64 description: Base document ID writeOnly: true baseLine: type: integer format: int32 description: Line number in the base document writeOnly: true baseQuantity: type: number description: Quantity to take from the base document line minimum: 0 writeOnly: true required: - productId - quantity OrderDocument: type: object description: Order ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Document primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (use in If-Match header) readOnly: true documentType: type: string description: Document type discriminator enum: - INVOICE - ORDER - DELIVERY_NOTE - QUOTE readOnly: true series: type: string description: Document series prefix example: A maxLength: 70 minLength: 0 number: type: integer format: int64 description: Sequential document number (server-assigned) example: 1234 readOnly: true code: type: string description: Full document code (series + number) example: A-1234 readOnly: true deliveryStatus: type: string description: Delivery status (P=not delivered, EP=partial, E=delivered) enum: - P - EP - E readOnly: true lifecycleStatus: type: string description: Regulatory lifecycle status readOnly: true paymentStatus: type: string description: Computed payment status enum: - UNPAID - PARTIAL - PAID - OVERPAID readOnly: true documentStatusId: type: integer format: int64 description: User-defined document status ID (Kanban) documentStatusName: type: string description: User-defined document status name readOnly: true issued: type: boolean description: true = outgoing (sales side), false = incoming (purchase side) draft: type: boolean description: Whether the document is still a draft readOnly: true enabled: type: boolean description: Whether the document is active (not logically deleted) readOnly: true verified: type: boolean description: Whether the document has been verified readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset; defaults to today on create if omitted) example: '2026-03-15T10:30:00+01:00' shippingDate: type: string description: Shipping / delivery date (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true counterpartyId: type: integer format: int64 description: Customer or supplier ID (required on create) example: 42 counterpartyName: type: string description: Customer or supplier name readOnly: true counterpartyTaxId: type: string description: Customer or supplier tax ID (NIF/CIF) readOnly: true agreementCounterpartyId: type: integer format: int64 description: Agreement counterparty ID (B2B convention party, e.g. mutual insurer) agreementCounterpartyName: type: string description: Agreement counterparty name readOnly: true companyId: type: integer format: int64 description: Issuing company ID example: 1 companyName: type: string description: Issuing company name readOnly: true companyTaxId: type: string description: Issuing company tax ID readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID (required on create) example: 1 warehouseName: type: string description: Warehouse / store name readOnly: true shippingAddressId: type: integer format: int64 description: Shipping address ID (existing address on create) shippingAddress: $ref: '#/components/schemas/AddressDto' description: Inline shipping address (created if no ID is given on create; denormalised on response) billingAddress: $ref: '#/components/schemas/AddressDto' description: Billing address (overrides counterparty default) employeeId: type: integer format: int64 description: Sales employee ID employeeName: type: string description: Sales employee name readOnly: true optometristId: type: integer format: int64 description: Optometrist ID optometristName: type: string description: Optometrist name readOnly: true documentTypeId: type: integer format: int64 description: User-defined document type ID documentTypeName: type: string description: User-defined document type name readOnly: true paymentTermsId: type: integer format: int64 description: Payment terms ID example: 1 paymentTermsName: type: string description: Payment terms description readOnly: true basePriceListId: type: integer format: int64 description: Base price list ID basePriceListName: type: string description: Base price list name readOnly: true discountPriceListId: type: integer format: int64 description: Discount price list ID discountPriceListName: type: string description: Discount price list name readOnly: true taxBehavior: type: string description: How tax is treated on prices enum: - INCLUDED - EXCLUDED - EXEMPT example: INCLUDED withholdingTaxTypeId: type: integer format: int64 description: Withholding tax type ID withholdingTaxTypeName: type: string description: Withholding tax type name readOnly: true internalRef: type: string description: Internal reference code example: REF-INT-001 maxLength: 40 minLength: 0 externalRef: type: string description: External reference (customer PO, etc.) example: PO-2026-789 maxLength: 255 minLength: 0 notes: type: string description: Free-text notes totalQuantity: type: number description: Sum of line quantities readOnly: true grossAmount: type: number description: Gross amount before discounts readOnly: true commercialNetAmount: type: number description: Operation net amount BEFORE insurer/customer copayment split. readOnly: true discountAmount: type: number description: Total commercial discount amount readOnly: true copaymentDiscount: type: number description: Insurance copayment discount readOnly: true specialDiscountPct: type: number description: Special discount percentage readOnly: true specialDiscountAmount: type: number description: Special discount amount readOnly: true earlyPaymentDiscountPct: type: number description: Early-payment discount percentage (pronto pago) earlyPaymentDiscount: type: number description: Early-payment discount amount (pronto pago) readOnly: true netAmount: type: number description: Taxable base / net amount readOnly: true vatAmount: type: number description: Total VAT amount readOnly: true surchargeEquivalencePct: type: number description: Surcharge equivalence percentage readOnly: true surchargeEquivalenceAmount: type: number description: Surcharge equivalence amount readOnly: true withholdingTaxBase: type: number description: 'Withholding tax base. Writable: overrides the derived base when the withholding does not apply to the full net.' withholdingTaxPct: type: number description: Withholding tax percentage (IRPF). Writable. withholdingOnFullNet: type: boolean description: >- When true the withholding percentage applies over the FULL document net (legacy irpfTotalDocumento); when false it applies over withholdingTaxBase. Full-state write: null/false apply the same (percentage over withholdingTaxBase); omit the key in a merge-patch to leave it unchanged. withholdingTaxAmount: type: number description: Withholding tax amount (primary) readOnly: true shippingAmount: type: number description: Shipping cost readOnly: true financingPct: type: number description: Financing surcharge percentage readOnly: true financingAmount: type: number description: Financing surcharge amount readOnly: true paymentMethodTaxAmount: type: number description: >- Payment-tax total (IGTF): sum of the per-payment paymentMethodTaxAmount quotas accrued by foreign-currency payments. Header aggregate with its own ledger account - NEVER distributed to lines, and excluded from product-margin analytics. The customer-facing grand total is total + paymentMethodTaxAmount. readOnly: true commercialTotalAmount: type: number description: Operation total (with VAT) BEFORE insurer/customer copayment split. readOnly: true total: type: number description: Document total readOnly: true totalPaid: type: number description: Amount already paid readOnly: true outstandingAmount: type: number description: Outstanding amount (total - totalPaid) readOnly: true currencyCode: type: string description: Document currency code (ISO 4217) example: EUR maxLength: 3 minLength: 3 currencyCodeSystem: type: string description: System / home currency code readOnly: true currencyDecimals: type: integer format: int32 description: >- Decimal places used to round monetary amounts in the document currency. Derived server-side from the business rule (0 for zero-decimal currencies such as CLP/COP/XOF/GMD, 2 otherwise); feed it to the client calc-engine CalcContext instead of hardcoding a table. example: 2 readOnly: true currencyDecimalsSystem: type: integer format: int32 description: Decimal places of the system / home currency (same derivation rule as currencyDecimals) example: 2 readOnly: true exchangeRate: type: number description: Exchange rate to system currency example: 1 minimum: 0 grossAmountSystem: type: number description: Gross amount in system currency readOnly: true discountAmountSystem: type: number description: Discount amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT amount in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true roundingMode: type: string description: Rounding mode applied readOnly: true relationConcept: type: string description: Inter-document relation concept readOnly: true relationType: type: string description: Inter-document relation type readOnly: true linkableQuantity: type: number description: Quantity still available for linking readOnly: true relationQuantity: type: number description: Quantity already linked readOnly: true totalApprovals: type: integer format: int32 description: Number of required approvals readOnly: true validatedApprovals: type: integer format: int32 description: Number of validated approvals readOnly: true relatedDocuments: type: array description: Documents related to this one items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true attachments: type: array description: File attachments items: $ref: '#/components/schemas/AttachmentRef' readOnly: true createdBy: type: string description: User who created the document readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: User who last modified the document readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business timezone offset) readOnly: true sourceSystem: type: string description: System that originated this document readOnly: true sapCode: type: string description: SAP document code readOnly: true lockType: type: string description: Lock type if the document is locked readOnly: true payments: type: array description: Inline payments registered against this document. Use the standalone POST /api/v2/payments to add more after creation. items: $ref: '#/components/schemas/PaymentDocument' lines: type: array description: Order line items items: $ref: '#/components/schemas/OrderLineDocument' trackingCode: type: string description: Shipping tracking code example: MRW-123456789 subscription: type: boolean description: Whether this is a subscription/recurring order subscriptionOrderId: type: integer format: int64 description: Original subscription order ID (for renewals) readOnly: true manufacturingDate: type: string description: Manufacturing date (ISO 8601 date-only) example: '2026-03-15' readOnly: true expiryDate: type: string description: Expiry date (ISO 8601 date-only) example: '2026-03-15' readOnly: true finishedUnits: type: number description: Finished / manufactured units readOnly: true soldOrder: type: boolean description: Whether the order has been fully sold readOnly: true fabricationStatus: type: string description: Manufacturing status readOnly: true lastFabricationStatusChange: type: string description: Last manufacturing status change (ISO 8601 with business timezone offset) readOnly: true required: - counterpartyId - warehouseId OrderLineDocument: type: object description: Order line ÔÇö read/write document. properties: id: type: integer format: int64 description: Line ID ÔÇö null on create for new lines, present to update an existing line lineNumber: type: integer format: int32 description: Sequential line number within the document readOnly: true productId: type: integer format: int64 description: Product ID (required on create) example: 1024 productName: type: string description: Line name shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived name. productDescription: type: string description: Line description shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived description. extendedDescription: type: string description: Additional line description packs: type: number description: Number of packs (unidades por pack ya resueltas) example: 2 batch: type: string description: Batch / lot text example: L-2026-03 expirationDate: type: string description: Batch expiration date (ISO 8601 date) example: '2027-06-30' unitPrice: type: number description: Unit price before discounts. Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA, WebPos Panama) are enforced server-side. example: 49.9 quantity: type: number description: >- Quantity (required on create). Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA credit notes require quantity <= -1) are enforced server-side. example: 2 grossAmount: type: number description: Gross amount (qty x price) readOnly: true discountPct: type: number description: Line discount percentage (0-100) example: 10 maximum: 100 minimum: 0 discountAmount: type: number description: Absolute discount amount (alternative to percentage) example: 5 minimum: 0 commercialNetAmount: type: number description: Line net amount BEFORE insurer/customer copayment split. readOnly: true copaymentDiscount: type: number description: Copayment discount (insurance) readOnly: true netAmount: type: number description: Taxable net amount readOnly: true vatTypeId: type: integer format: int64 description: VAT type ID example: 1 vatTypeName: type: string description: VAT type name readOnly: true vatPct: type: number description: VAT percentage readOnly: true vatAmount: type: number description: VAT amount readOnly: true manualVatAmount: type: number description: >- Manual VAT amount override. Input-only intent: when set on a write it replaces the computed line VAT (legacy 'IVA manual'); never returned by GET (read vatAmount instead), so omitting/null leaves the computed VAT untouched. writeOnly: true manualSurchargeAmount: type: number description: 'Manual surcharge amount override (legacy ''RE manual''). Input-only intent: never returned by GET (read surchargeAmount instead).' writeOnly: true surchargeTypeId: type: integer format: int64 description: Surcharge equivalence type ID surchargeTypeName: type: string description: Surcharge type name readOnly: true surchargePct: type: number description: Surcharge percentage readOnly: true surchargeAmount: type: number description: Surcharge amount readOnly: true total: type: number description: Line total (net + VAT + surcharge) readOnly: true commercialTotalAmount: type: number description: Line total (with VAT) BEFORE insurer/customer copayment split. readOnly: true discounts: type: array description: >- Line discount elements (insurer contribution, discount PIN, points redemption) applied AFTER the commercial discount. On writes: null = leave untouched; a list = reconcile (present elements are applied/updated via the pricing engine ÔÇö caps enforced ÔÇö, absent elements are removed). items: $ref: '#/components/schemas/LineDiscountDocument' appliedPriceRule: $ref: '#/components/schemas/AppliedPriceRuleDocument' description: Pricing rule the backend applied to this line (tariff discount, combo or PIN). Explains the commercial discount origin. readOnly: true excludedTariffIds: type: array description: Tariff IDs excluded from automatic pricing on this line (promotion opt-out). The sentinel -1 (exclude PIN) is managed through excludePin instead. items: type: integer format: int64 excludePin: type: boolean description: Exclude the document discount PIN from this line campaignId: type: integer format: int64 description: Campaign / promotion ID campaignName: type: string description: Campaign name readOnly: true grossAmountSystem: type: number description: Gross amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true reservedQuantity: type: number description: Reserved stock quantity readOnly: true vatAccountId: type: integer format: int64 description: VAT ledger account ID surchargeAccountId: type: integer format: int64 description: Surcharge equivalence ledger account ID revenueAccountId: type: integer format: int64 description: Revenue ledger account ID relatedDocuments: type: array description: Related documents linked to this line items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true opticalOrderId: type: integer format: int64 description: ID of the optical order (encargo) this line belongs to. readOnly: true baseType: type: string description: Base document type enum: - ORDER - DELIVERY_NOTE - INVOICE - QUOTE writeOnly: true baseEntry: type: integer format: int64 description: Base document ID writeOnly: true baseLine: type: integer format: int32 description: Line number in the base document writeOnly: true baseQuantity: type: number description: Quantity to take from the base document line minimum: 0 writeOnly: true receivedQuantity: type: number description: Received quantity (for purchase orders) readOnly: true required: - productId - quantity CapabilityDocument: type: object description: >- Whether a field group or action is allowed for the current document state and authenticated user. When not allowed, `code` carries a stable machine-readable cause and `reason` a human-readable explanation. properties: allowed: type: boolean description: Whether the field group / action is allowed code: type: string description: Stable machine-readable cause when not allowed enum: - LOCK_TYPE - VERIFACTU_STATE - OLA_MODE - OLA_CREDIT_NOTE - FISCAL_PRINTER_VE - CREDIT_NOTE_TYPE - MISSING_PERMISSION - ORDER_CONTROL - AGENT_LOCK example: VERIFACTU_STATE reason: type: string description: Human-readable explanation when not allowed ElectronicInvoiceDocument: type: object description: Electronic-invoicing data attached to the invoice (mirror of FacturaSIICabecera). Unified read/write document. properties: id: type: integer format: int64 description: Primary key of the electronic-invoicing row (con_factura_siicabecera.id). readOnly: true signStatus: type: string description: Cross-regime sign status of the electronic-invoicing flow. Triggers a fiscal state transition on the parent invoice when supplied on input. enum: - PENDING - SIGNED - RECEIVED_PENDING - REJECTED - SUBMIT_ERROR signedAt: type: string format: date-time description: UTC instant when the fiscal authority responded. example: '2026-05-24T17:42:13.512Z' lastSignErrorCode: type: string description: Stable error code returned by the fiscal authority or by the internal submission pipeline. example: DGI-12-INVALID-RUC maxLength: 100 minLength: 0 lastSignErrorMessage: type: string description: Human-readable error message returned by the fiscal authority or the internal pipeline. maxLength: 500 minLength: 0 sunatHash: type: string description: SHA-1 hash of the signed XML sent to SUNAT. example: 9c1185a5c5e9fc54612808977ee8f548b2258d31 maxLength: 60 minLength: 0 sunatInvoiceCode: type: string description: Invoice identifier returned by SUNAT in the CDR. example: 1000-0001-00000001 maxLength: 25 minLength: 0 sunatQrCode: type: string description: QR code (base64-encoded PNG) for the SUNAT (Per├║) electronic invoice. example: iVBORw0KGgoAAAANSUhEUgÔǪ dgiCufe: type: string description: CUFE ÔÇö C├│digo ├Ünico de Factura Electr├│nica (DGI Panam├í). Persisted with aliasing in con_factura.errorSII. example: FE012026...01D2 maxLength: 255 minLength: 0 dgiAuthorizationNumber: type: string description: Authorization number returned by DGI Panam├í. Persisted in con_factura.codNumAutorizacion. example: FE0120260524174213512 maxLength: 50 minLength: 0 dgiSecNumber: type: string description: DGI sequential number (secNumber). Persisted with aliasing in con_factura.nro_siniestro. example: '00000123' maxLength: 30 minLength: 0 dgiDv: type: string description: Issuer DV (D├¡gito Verificador) ÔÇö Panam├í. Persisted with aliasing in con_factura.nro_cedula. example: '5' maxLength: 5 minLength: 0 dgiQrCode: type: string description: QR code (base64-encoded PNG) for DGI Panam├í. Persisted in con_factura_siicabecera.qrBase64. example: iVBORw0KGgoAAAANSUhEUgÔǪ dgiSystemRef: type: string description: Internal reference of the PAC / external system. Persisted with aliasing in con_factura_siicabecera.referenciaCatastral. example: DGI-WEBPOS-2026-0001234 maxLength: 100 minLength: 0 InstallmentDocument: type: object description: 'Payment installment / due date entry (vencimiento). On input: null list = leave untouched; empty list = delete all unpaid; non-empty list = upsert by id. Paid installments are immutable.' properties: id: type: integer format: int64 description: Installment primary key (upsert key on writes; omit to create) example: 801 version: type: integer format: int32 description: Optimistic lock version readOnly: true dueDate: type: string description: Due date (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' amount: type: number description: Installment amount example: 250 paid: type: boolean description: Whether the installment has been paid readOnly: true issued: type: boolean description: Whether the installment has been issued readOnly: true paymentMethodId: type: integer format: int64 description: Payment method ID paymentMethodName: type: string description: Payment method name readOnly: true paymentAccountId: type: integer format: int64 description: Payment account ID paymentAccountName: type: string description: Payment account name readOnly: true paymentId: type: integer format: int64 description: Payment ID that settled this installment readOnly: true withholdingLineId: type: integer format: int64 description: Withholding tax line ID readOnly: true amountSystem: type: number description: Amount in system currency readOnly: true exchangeRate: type: number description: Exchange rate to system currency readOnly: true currencyCode: type: string description: Currency code (ISO 4217) example: EUR readOnly: true currencyCodeSystem: type: string description: System currency code readOnly: true withholdingTaxPct: type: number description: Withholding tax percentage readOnly: true required: - amount InvoiceCapabilitiesDocument: type: object description: 'Server-resolved editability matrix for the invoice (lock flags, fiscal lifecycle, company mode and user permissions). Purely informative for the client: the server re-validates on write.' properties: header: $ref: '#/components/schemas/CapabilityDocument' description: Header fields (references, dates without own permission, classification) counterparty: $ref: '#/components/schemas/CapabilityDocument' description: Counterparty (customer) selection and fiscal snapshot documentDate: $ref: '#/components/schemas/CapabilityDocument' description: Document date (permission EDITAR_FECHA_FACTURA_VENTA/COMPRA) internalFields: $ref: '#/components/schemas/CapabilityDocument' description: Internal fields (payment terms, employee) amounts: $ref: '#/components/schemas/CapabilityDocument' description: Document amount fields (price lists, VAT indicator, IRPF, manual taxes) unitPrices: $ref: '#/components/schemas/CapabilityDocument' description: Line unit prices / PVP (permission EDITAR_PRECUNI_*) manualDiscounts: $ref: '#/components/schemas/CapabilityDocument' description: Line manual discounts (permission EDITAR_DESCMAN_*) lineDescriptions: $ref: '#/components/schemas/CapabilityDocument' description: Line name/description edition (permission EDITAR_DESCART_*) products: $ref: '#/components/schemas/CapabilityDocument' description: Adding/removing products (lines) quantities: $ref: '#/components/schemas/CapabilityDocument' description: Line quantities accounting: $ref: '#/components/schemas/CapabilityDocument' description: Accounting fields (accounting date, accounts, journal linkage) payments: $ref: '#/components/schemas/CapabilityDocument' description: Payments (cobros) edition insurerAmounts: $ref: '#/components/schemas/CapabilityDocument' description: Insurer contribution amounts per line (permission EDITAR_IMPORTES_ASEGURADORA) costCenters: $ref: '#/components/schemas/CapabilityDocument' description: Cost centers (permission VER_CENTROSCOSTE + lock flag) opticalOrders: $ref: '#/components/schemas/CapabilityDocument' description: Creating optical orders (encargos) from the invoice edit: $ref: '#/components/schemas/CapabilityDocument' description: Whether the invoice can be edited at all (e.g. Venezuelan fiscal printer forbids editing persisted invoices) delete: $ref: '#/components/schemas/CapabilityDocument' description: Whether the invoice can be deleted InvoiceDocument: type: object description: >- Invoice ÔÇö unified read/write document. Inherits the shared sales-document fields from SalesDocument and adds the invoice-specific surface (accounting, classification, insurance, loyalty, electronic invoicing, lines). properties: id: type: integer format: int64 description: Document primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (use in If-Match header) readOnly: true documentType: type: string description: Document type discriminator enum: - INVOICE - ORDER - DELIVERY_NOTE - QUOTE readOnly: true series: type: string description: Document series prefix example: A maxLength: 70 minLength: 0 number: type: integer format: int64 description: Sequential document number (server-assigned) example: 1234 readOnly: true code: type: string description: Full document code (series + number) example: A-1234 readOnly: true deliveryStatus: type: string description: Delivery status (P=not delivered, EP=partial, E=delivered) enum: - P - EP - E readOnly: true lifecycleStatus: type: string description: Regulatory lifecycle status readOnly: true paymentStatus: type: string description: Computed payment status enum: - UNPAID - PARTIAL - PAID - OVERPAID readOnly: true documentStatusId: type: integer format: int64 description: User-defined document status ID (Kanban) documentStatusName: type: string description: User-defined document status name readOnly: true issued: type: boolean description: true = outgoing (sales side), false = incoming (purchase side) draft: type: boolean description: Whether the document is still a draft readOnly: true enabled: type: boolean description: Whether the document is active (not logically deleted) readOnly: true verified: type: boolean description: Whether the document has been verified readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset; defaults to today on create if omitted) example: '2026-03-15T10:30:00+01:00' shippingDate: type: string description: Shipping / delivery date (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true counterpartyId: type: integer format: int64 description: Customer or supplier ID (required on create) example: 42 counterpartyName: type: string description: Customer or supplier name readOnly: true counterpartyTaxId: type: string description: Customer or supplier tax ID (NIF/CIF) readOnly: true agreementCounterpartyId: type: integer format: int64 description: Agreement counterparty ID (B2B convention party, e.g. mutual insurer) agreementCounterpartyName: type: string description: Agreement counterparty name readOnly: true companyId: type: integer format: int64 description: Issuing company ID example: 1 companyName: type: string description: Issuing company name readOnly: true companyTaxId: type: string description: Issuing company tax ID readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID (required on create) example: 1 warehouseName: type: string description: Warehouse / store name readOnly: true shippingAddressId: type: integer format: int64 description: Shipping address ID (existing address on create) shippingAddress: $ref: '#/components/schemas/AddressDto' description: Inline shipping address (created if no ID is given on create; denormalised on response) billingAddress: $ref: '#/components/schemas/AddressDto' description: Billing address (overrides counterparty default) employeeId: type: integer format: int64 description: Sales employee ID employeeName: type: string description: Sales employee name readOnly: true optometristId: type: integer format: int64 description: Optometrist ID optometristName: type: string description: Optometrist name readOnly: true documentTypeId: type: integer format: int64 description: User-defined document type ID documentTypeName: type: string description: User-defined document type name readOnly: true paymentTermsId: type: integer format: int64 description: Payment terms ID example: 1 paymentTermsName: type: string description: Payment terms description readOnly: true basePriceListId: type: integer format: int64 description: Base price list ID basePriceListName: type: string description: Base price list name readOnly: true discountPriceListId: type: integer format: int64 description: Discount price list ID discountPriceListName: type: string description: Discount price list name readOnly: true taxBehavior: type: string description: How tax is treated on prices enum: - INCLUDED - EXCLUDED - EXEMPT example: INCLUDED withholdingTaxTypeId: type: integer format: int64 description: Withholding tax type ID withholdingTaxTypeName: type: string description: Withholding tax type name readOnly: true internalRef: type: string description: Internal reference code example: REF-INT-001 maxLength: 40 minLength: 0 externalRef: type: string description: External reference (customer PO, etc.) example: PO-2026-789 maxLength: 255 minLength: 0 notes: type: string description: Free-text notes totalQuantity: type: number description: Sum of line quantities readOnly: true grossAmount: type: number description: Gross amount before discounts readOnly: true commercialNetAmount: type: number description: Operation net amount BEFORE insurer/customer copayment split. readOnly: true discountAmount: type: number description: Total commercial discount amount readOnly: true copaymentDiscount: type: number description: Insurance copayment discount readOnly: true specialDiscountPct: type: number description: Special discount percentage readOnly: true specialDiscountAmount: type: number description: Special discount amount readOnly: true earlyPaymentDiscountPct: type: number description: Early-payment discount percentage (pronto pago) earlyPaymentDiscount: type: number description: Early-payment discount amount (pronto pago) readOnly: true netAmount: type: number description: Taxable base / net amount readOnly: true vatAmount: type: number description: Total VAT amount readOnly: true surchargeEquivalencePct: type: number description: Surcharge equivalence percentage readOnly: true surchargeEquivalenceAmount: type: number description: Surcharge equivalence amount readOnly: true withholdingTaxBase: type: number description: 'Withholding tax base. Writable: overrides the derived base when the withholding does not apply to the full net.' withholdingTaxPct: type: number description: Withholding tax percentage (IRPF). Writable. withholdingOnFullNet: type: boolean description: >- When true the withholding percentage applies over the FULL document net (legacy irpfTotalDocumento); when false it applies over withholdingTaxBase. Full-state write: null/false apply the same (percentage over withholdingTaxBase); omit the key in a merge-patch to leave it unchanged. withholdingTaxAmount: type: number description: Withholding tax amount (primary) readOnly: true shippingAmount: type: number description: Shipping cost readOnly: true financingPct: type: number description: Financing surcharge percentage readOnly: true financingAmount: type: number description: Financing surcharge amount readOnly: true paymentMethodTaxAmount: type: number description: >- Payment-tax total (IGTF): sum of the per-payment paymentMethodTaxAmount quotas accrued by foreign-currency payments. Header aggregate with its own ledger account - NEVER distributed to lines, and excluded from product-margin analytics. The customer-facing grand total is total + paymentMethodTaxAmount. readOnly: true commercialTotalAmount: type: number description: Operation total (with VAT) BEFORE insurer/customer copayment split. readOnly: true total: type: number description: Document total readOnly: true totalPaid: type: number description: Amount already paid readOnly: true outstandingAmount: type: number description: Outstanding amount (total - totalPaid) readOnly: true currencyCode: type: string description: Document currency code (ISO 4217) example: EUR maxLength: 3 minLength: 3 currencyCodeSystem: type: string description: System / home currency code readOnly: true currencyDecimals: type: integer format: int32 description: >- Decimal places used to round monetary amounts in the document currency. Derived server-side from the business rule (0 for zero-decimal currencies such as CLP/COP/XOF/GMD, 2 otherwise); feed it to the client calc-engine CalcContext instead of hardcoding a table. example: 2 readOnly: true currencyDecimalsSystem: type: integer format: int32 description: Decimal places of the system / home currency (same derivation rule as currencyDecimals) example: 2 readOnly: true exchangeRate: type: number description: Exchange rate to system currency example: 1 minimum: 0 grossAmountSystem: type: number description: Gross amount in system currency readOnly: true discountAmountSystem: type: number description: Discount amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT amount in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true roundingMode: type: string description: Rounding mode applied readOnly: true relationConcept: type: string description: Inter-document relation concept readOnly: true relationType: type: string description: Inter-document relation type readOnly: true linkableQuantity: type: number description: Quantity still available for linking readOnly: true relationQuantity: type: number description: Quantity already linked readOnly: true totalApprovals: type: integer format: int32 description: Number of required approvals readOnly: true validatedApprovals: type: integer format: int32 description: Number of validated approvals readOnly: true relatedDocuments: type: array description: Documents related to this one items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true attachments: type: array description: File attachments items: $ref: '#/components/schemas/AttachmentRef' readOnly: true createdBy: type: string description: User who created the document readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: User who last modified the document readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business timezone offset) readOnly: true sourceSystem: type: string description: System that originated this document readOnly: true sapCode: type: string description: SAP document code readOnly: true lockType: type: string description: Lock type if the document is locked readOnly: true payments: type: array description: Inline payments registered against this document. Use the standalone POST /api/v2/payments to add more after creation. items: $ref: '#/components/schemas/PaymentDocument' lines: type: array description: Invoice line items (at least one required on create/update) items: $ref: '#/components/schemas/InvoiceLineDocument' minItems: 1 pricesIncludeTax: type: boolean description: >- When true, each line's unitPrice is interpreted as a VAT-INCLUSIVE (gross) unit price and the net price is back-calculated from the line VAT rate (mirrors the legacy WooCommerce/Shopify ticket import, which treats the shop price as PVP con IVA). Default false = unitPrice is net and VAT is added on top. generateDeliveryNote: type: boolean description: >- When true, after the invoice is created the server also generates a linked delivery note (albaran de entrega) via the Copiador (relation A_F / concepto ENTREGA). The invoice reserves stock; the linked delivery note consumes that reservation and moves the physical stock (single stock-out, no double count). Mirrors the legacy GMSystemConnector.generarAlbaranDesdeFactura used by FacturaMapper. Default false = no delivery note (the e-commerce ticket import sets it true when the subscription enables it). issueDate: type: string description: >- Issue/expedition date (ISO 8601 with business timezone offset). On create defaults to documentDate; if documentDate is also absent, defaults to today. Differs from documentDate only on the ticket->full-invoice exchange (documentDate keeps the operation date, issueDate is the day the invoice was issued). accountingDate: type: string description: Accounting date (ISO 8601 with business timezone offset; defaults to documentDate on create if omitted) receptionDate: type: string description: Date the invoice was received (ISO 8601 with business timezone offset, only for purchase invoices) counterpartyType: type: string description: >- Denormalised counterparty identification type at document time (TipoTercero enum: PF, E, CC, PA, ...). Snapshot of the counterparty's identification type when the invoice was created; defaults from the counterparty master on create when omitted. On writes it is re-derived from the selected counterparty; send an explicit value to OVERRIDE the snapshot. Omitting it (or null) keeps the counterparty-derived value. enum: - PF - E - CC - PA - G - DC - B - CE - TE - CD - SC - PE - RC - TI - AS - MS - DE - SI - CX - CF - CJ - D - 'N' - EX example: PF totalWithholdings: type: number description: Total withholding tax (sum of all multi-line IRPF withholdings) readOnly: true accountingNumber: type: string description: Accounting entry number readOnly: true journalEntryId: type: integer format: int64 description: Journal entry ID readOnly: true accountingLedger: type: integer format: int32 description: Accounting ledger number example: 1 linkedToAccounting: type: boolean description: Whether linked to accounting counterpartyAccountId: type: integer format: int64 description: Counterparty ledger account ID counterpartyAccountName: type: string description: Counterparty ledger account name readOnly: true withholdingTaxAccountId: type: integer format: int64 description: Withholding tax ledger account ID withholdingTaxAccountName: type: string description: Withholding tax ledger account name readOnly: true activityId: type: integer format: int64 description: 'Business activity ID (actividad). Writable on full-state writes: null CLEARS the activity; omit the key in a merge-patch to leave it unchanged.' activityName: type: string description: Business activity name readOnly: true invoiceType: type: string description: Invoice type enum: - SUS - SUB readOnly: true simplified: type: boolean description: Whether this is a simplified invoice (ticket) creditNoteType: type: string description: Credit note sub-type readOnly: true saleCondition: type: string description: Sale condition code reverseCharge: type: boolean description: Reverse charge (VAT paid by recipient) intraCommunity: type: boolean description: Intra-community operation insuranceInvoice: type: boolean description: Insurance-related invoice visitReasonId: type: integer format: int64 description: Visit reason ID visitReasonName: type: string description: Visit reason name readOnly: true primaryInsurerId: type: integer format: int64 description: Primary insurer ID primaryInsurerName: type: string description: Primary insurer name readOnly: true secondaryInsurerId: type: integer format: int64 description: Secondary insurer ID secondaryInsurerName: type: string description: Secondary insurer name readOnly: true tertiaryInsurerId: type: integer format: int64 description: Tertiary insurer ID tertiaryInsurerName: type: string description: Tertiary insurer name readOnly: true primaryContractNumber: type: string description: Primary contract number secondaryContractNumber: type: string description: Secondary contract number tertiaryContractNumber: type: string description: Tertiary contract number primaryBeneficiaryNumber: type: string description: Primary beneficiary number secondaryBeneficiaryNumber: type: string description: Secondary beneficiary number tertiaryBeneficiaryNumber: type: string description: Tertiary beneficiary number insuredPartyId: type: integer format: int64 description: Insured party ID insuredPartyName: type: string description: Insured party name readOnly: true insuredNationalId: type: string description: Insured party national ID insuredPolicyNumber: type: string description: Insurance policy number insuredClaimNumber: type: string description: Insurance claim number pointsWalletId: type: integer format: int64 description: Points wallet ID (cartera de puntos) readOnly: true pointsWalletToRedeemId: type: integer format: int64 description: 'Points wallet the redemption draws from (cartera de canje). Writable on full-state writes: null CLEARS the wallet; omit the key in a merge-patch to leave it unchanged.' customerPointsBalance: type: number description: Customer's current points balance readOnly: true pointsEarned: type: number description: Points earned with this invoice readOnly: true pointsRedeemed: type: number description: Points actually redeemed (server outcome) readOnly: true pointsToRedeem: type: number description: Loyalty points to redeem (input intent) example: 50 minimum: 0 writeOnly: true pointsValueAmount: type: number description: Monetary value of redeemed points readOnly: true opticalDataId: type: integer format: int64 description: Optical data record ID readOnly: true discountPinId: type: integer format: int64 description: >- Discount PIN ID. Writable on full-state writes: assigning a PIN cascades its discount over the eligible lines through the pricing engine; null CLEARS the PIN; omit the key in a merge-patch to leave it unchanged. claimId: type: integer format: int64 description: Insurance claim ID readOnly: true installments: type: array description: >- Payment installments / due dates (vencimientos). On writes: null = leave existing installments untouched; [] = delete all unpaid installments; non-empty list = upsert by id (entries without id are created, persisted unpaid installments missing from the list are removed). Paid installments are immutable. items: $ref: '#/components/schemas/InstallmentDocument' totalInstallments: type: integer format: int32 description: Total number of installments readOnly: true paidInstallments: type: integer format: int32 description: Number of paid installments readOnly: true electronicInvoice: $ref: '#/components/schemas/ElectronicInvoiceDocument' description: 'Electronic-invoicing data (mirror of FacturaSIICabecera). On input: null = leave existing data untouched; empty object = clear SUNAT fields; non-null with values = allocate/update.' verifactuStatus: type: string description: Verifactu submission status readOnly: true verifactuReady: type: boolean description: Whether ready for Verifactu submission readOnly: true cfdiUsage: type: string description: CFDI usage code (Mexico SAT) readOnly: true satPaymentMethod: type: string description: SAT payment method code (Mexico) readOnly: true cancellationRecordId: type: integer format: int64 description: ID of the SAT cancellation record readOnly: true folioNumber: type: integer format: int64 description: Electronic invoice folio number readOnly: true establishmentCode: type: string description: Establishment code (Ecuador) readOnly: true emissionPointCode: type: string description: Emission point code (Ecuador) readOnly: true authorizationCode: type: string description: Electronic invoice authorization code (Ecuador) readOnly: true global: type: boolean description: Whether this is a global invoice (SAT M├®xico aggregator) readOnly: true globalInvoiceId: type: integer format: int64 description: Parent global invoice ID readOnly: true fiscalDocumentNumber: type: integer format: int64 description: Fiscal document number readOnly: true fiscalPrinterSerial: type: string description: Fiscal printer serial readOnly: true sunatPaymentMethod: type: string description: SUNAT payment method (Cat├ílogo SUNAT). CO = Contado (cash), CR = Cr├®dito (credit). enum: - CO - CR example: CO maxLength: 2 minLength: 0 capabilities: $ref: '#/components/schemas/InvoiceCapabilitiesDocument' description: >- Server-resolved editability matrix (lock flags, fiscal lifecycle, company mode and user permissions). Present on WAR-produced responses (prepare/create/update) and on GET /api/v2/sales-invoices/{id}/capabilities. Ignored on writes. readOnly: true einvoiceError: type: string einvoiceXmlUrl: type: string required: - counterpartyId - lines - warehouseId InvoiceLineDocument: type: object description: Invoice line ÔÇö read/write document. properties: id: type: integer format: int64 description: Line ID ÔÇö null on create for new lines, present to update an existing line lineNumber: type: integer format: int32 description: Sequential line number within the document readOnly: true productId: type: integer format: int64 description: Product ID (required on create) example: 1024 productName: type: string description: Line name shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived name. productDescription: type: string description: Line description shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived description. extendedDescription: type: string description: Additional line description packs: type: number description: Number of packs (unidades por pack ya resueltas) example: 2 batch: type: string description: Batch / lot text example: L-2026-03 expirationDate: type: string description: Batch expiration date (ISO 8601 date) example: '2027-06-30' unitPrice: type: number description: Unit price before discounts. Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA, WebPos Panama) are enforced server-side. example: 49.9 quantity: type: number description: >- Quantity (required on create). Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA credit notes require quantity <= -1) are enforced server-side. example: 2 grossAmount: type: number description: Gross amount (qty x price) readOnly: true discountPct: type: number description: Line discount percentage (0-100) example: 10 maximum: 100 minimum: 0 discountAmount: type: number description: Absolute discount amount (alternative to percentage) example: 5 minimum: 0 commercialNetAmount: type: number description: Line net amount BEFORE insurer/customer copayment split. readOnly: true copaymentDiscount: type: number description: Copayment discount (insurance) readOnly: true netAmount: type: number description: Taxable net amount readOnly: true vatTypeId: type: integer format: int64 description: VAT type ID example: 1 vatTypeName: type: string description: VAT type name readOnly: true vatPct: type: number description: VAT percentage readOnly: true vatAmount: type: number description: VAT amount readOnly: true manualVatAmount: type: number description: >- Manual VAT amount override. Input-only intent: when set on a write it replaces the computed line VAT (legacy 'IVA manual'); never returned by GET (read vatAmount instead), so omitting/null leaves the computed VAT untouched. writeOnly: true manualSurchargeAmount: type: number description: 'Manual surcharge amount override (legacy ''RE manual''). Input-only intent: never returned by GET (read surchargeAmount instead).' writeOnly: true surchargeTypeId: type: integer format: int64 description: Surcharge equivalence type ID surchargeTypeName: type: string description: Surcharge type name readOnly: true surchargePct: type: number description: Surcharge percentage readOnly: true surchargeAmount: type: number description: Surcharge amount readOnly: true total: type: number description: Line total (net + VAT + surcharge) readOnly: true commercialTotalAmount: type: number description: Line total (with VAT) BEFORE insurer/customer copayment split. readOnly: true discounts: type: array description: >- Line discount elements (insurer contribution, discount PIN, points redemption) applied AFTER the commercial discount. On writes: null = leave untouched; a list = reconcile (present elements are applied/updated via the pricing engine ÔÇö caps enforced ÔÇö, absent elements are removed). items: $ref: '#/components/schemas/LineDiscountDocument' appliedPriceRule: $ref: '#/components/schemas/AppliedPriceRuleDocument' description: Pricing rule the backend applied to this line (tariff discount, combo or PIN). Explains the commercial discount origin. readOnly: true excludedTariffIds: type: array description: Tariff IDs excluded from automatic pricing on this line (promotion opt-out). The sentinel -1 (exclude PIN) is managed through excludePin instead. items: type: integer format: int64 excludePin: type: boolean description: Exclude the document discount PIN from this line campaignId: type: integer format: int64 description: Campaign / promotion ID campaignName: type: string description: Campaign name readOnly: true grossAmountSystem: type: number description: Gross amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true reservedQuantity: type: number description: Reserved stock quantity readOnly: true vatAccountId: type: integer format: int64 description: VAT ledger account ID surchargeAccountId: type: integer format: int64 description: Surcharge equivalence ledger account ID revenueAccountId: type: integer format: int64 description: Revenue ledger account ID relatedDocuments: type: array description: Related documents linked to this line items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true opticalOrderId: type: integer format: int64 description: ID of the optical order (encargo) this line belongs to. readOnly: true baseType: type: string description: Base document type enum: - ORDER - DELIVERY_NOTE - INVOICE - QUOTE writeOnly: true baseEntry: type: integer format: int64 description: Base document ID writeOnly: true baseLine: type: integer format: int32 description: Line number in the base document writeOnly: true baseQuantity: type: number description: Quantity to take from the base document line minimum: 0 writeOnly: true deliveryStatus: type: string description: Delivery status (PENDING, PARTIAL, DELIVERED) readOnly: true sunatUnitOfMeasure: type: string description: SUNAT unit of measure code (Cat├ílogo SUNAT N.┬║ 03, UN/ECE Recommendation 20). NIU = unit of goods, ZZ = unit of services. enum: - NIU - ZZ example: NIU maxLength: 3 minLength: 0 required: - productId - quantity SalesDeliveryNoteDocument: type: object description: Sales delivery note ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Document primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (use in If-Match header) readOnly: true documentType: type: string description: Document type discriminator enum: - INVOICE - ORDER - DELIVERY_NOTE - QUOTE readOnly: true series: type: string description: Document series prefix example: A maxLength: 70 minLength: 0 number: type: integer format: int64 description: Sequential document number (server-assigned) example: 1234 readOnly: true code: type: string description: Full document code (series + number) example: A-1234 readOnly: true deliveryStatus: type: string description: Delivery status (P=not delivered, EP=partial, E=delivered) enum: - P - EP - E readOnly: true lifecycleStatus: type: string description: Regulatory lifecycle status readOnly: true paymentStatus: type: string description: Computed payment status enum: - UNPAID - PARTIAL - PAID - OVERPAID readOnly: true documentStatusId: type: integer format: int64 description: User-defined document status ID (Kanban) documentStatusName: type: string description: User-defined document status name readOnly: true issued: type: boolean description: true = outgoing (sales side), false = incoming (purchase side) draft: type: boolean description: Whether the document is still a draft readOnly: true enabled: type: boolean description: Whether the document is active (not logically deleted) readOnly: true verified: type: boolean description: Whether the document has been verified readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset; defaults to today on create if omitted) example: '2026-03-15T10:30:00+01:00' shippingDate: type: string description: Shipping / delivery date (ISO 8601 with business timezone offset) example: '2026-03-15T10:30:00+01:00' readOnly: true counterpartyId: type: integer format: int64 description: Customer or supplier ID (required on create) example: 42 counterpartyName: type: string description: Customer or supplier name readOnly: true counterpartyTaxId: type: string description: Customer or supplier tax ID (NIF/CIF) readOnly: true agreementCounterpartyId: type: integer format: int64 description: Agreement counterparty ID (B2B convention party, e.g. mutual insurer) agreementCounterpartyName: type: string description: Agreement counterparty name readOnly: true companyId: type: integer format: int64 description: Issuing company ID example: 1 companyName: type: string description: Issuing company name readOnly: true companyTaxId: type: string description: Issuing company tax ID readOnly: true warehouseId: type: integer format: int64 description: Warehouse / store ID (required on create) example: 1 warehouseName: type: string description: Warehouse / store name readOnly: true shippingAddressId: type: integer format: int64 description: Shipping address ID (existing address on create) shippingAddress: $ref: '#/components/schemas/AddressDto' description: Inline shipping address (created if no ID is given on create; denormalised on response) billingAddress: $ref: '#/components/schemas/AddressDto' description: Billing address (overrides counterparty default) employeeId: type: integer format: int64 description: Sales employee ID employeeName: type: string description: Sales employee name readOnly: true optometristId: type: integer format: int64 description: Optometrist ID optometristName: type: string description: Optometrist name readOnly: true documentTypeId: type: integer format: int64 description: User-defined document type ID documentTypeName: type: string description: User-defined document type name readOnly: true paymentTermsId: type: integer format: int64 description: Payment terms ID example: 1 paymentTermsName: type: string description: Payment terms description readOnly: true basePriceListId: type: integer format: int64 description: Base price list ID basePriceListName: type: string description: Base price list name readOnly: true discountPriceListId: type: integer format: int64 description: Discount price list ID discountPriceListName: type: string description: Discount price list name readOnly: true taxBehavior: type: string description: How tax is treated on prices enum: - INCLUDED - EXCLUDED - EXEMPT example: INCLUDED withholdingTaxTypeId: type: integer format: int64 description: Withholding tax type ID withholdingTaxTypeName: type: string description: Withholding tax type name readOnly: true internalRef: type: string description: Internal reference code example: REF-INT-001 maxLength: 40 minLength: 0 externalRef: type: string description: External reference (customer PO, etc.) example: PO-2026-789 maxLength: 255 minLength: 0 notes: type: string description: Free-text notes totalQuantity: type: number description: Sum of line quantities readOnly: true grossAmount: type: number description: Gross amount before discounts readOnly: true commercialNetAmount: type: number description: Operation net amount BEFORE insurer/customer copayment split. readOnly: true discountAmount: type: number description: Total commercial discount amount readOnly: true copaymentDiscount: type: number description: Insurance copayment discount readOnly: true specialDiscountPct: type: number description: Special discount percentage readOnly: true specialDiscountAmount: type: number description: Special discount amount readOnly: true earlyPaymentDiscountPct: type: number description: Early-payment discount percentage (pronto pago) earlyPaymentDiscount: type: number description: Early-payment discount amount (pronto pago) readOnly: true netAmount: type: number description: Taxable base / net amount readOnly: true vatAmount: type: number description: Total VAT amount readOnly: true surchargeEquivalencePct: type: number description: Surcharge equivalence percentage readOnly: true surchargeEquivalenceAmount: type: number description: Surcharge equivalence amount readOnly: true withholdingTaxBase: type: number description: 'Withholding tax base. Writable: overrides the derived base when the withholding does not apply to the full net.' withholdingTaxPct: type: number description: Withholding tax percentage (IRPF). Writable. withholdingOnFullNet: type: boolean description: >- When true the withholding percentage applies over the FULL document net (legacy irpfTotalDocumento); when false it applies over withholdingTaxBase. Full-state write: null/false apply the same (percentage over withholdingTaxBase); omit the key in a merge-patch to leave it unchanged. withholdingTaxAmount: type: number description: Withholding tax amount (primary) readOnly: true shippingAmount: type: number description: Shipping cost readOnly: true financingPct: type: number description: Financing surcharge percentage readOnly: true financingAmount: type: number description: Financing surcharge amount readOnly: true paymentMethodTaxAmount: type: number description: >- Payment-tax total (IGTF): sum of the per-payment paymentMethodTaxAmount quotas accrued by foreign-currency payments. Header aggregate with its own ledger account - NEVER distributed to lines, and excluded from product-margin analytics. The customer-facing grand total is total + paymentMethodTaxAmount. readOnly: true commercialTotalAmount: type: number description: Operation total (with VAT) BEFORE insurer/customer copayment split. readOnly: true total: type: number description: Document total readOnly: true totalPaid: type: number description: Amount already paid readOnly: true outstandingAmount: type: number description: Outstanding amount (total - totalPaid) readOnly: true currencyCode: type: string description: Document currency code (ISO 4217) example: EUR maxLength: 3 minLength: 3 currencyCodeSystem: type: string description: System / home currency code readOnly: true currencyDecimals: type: integer format: int32 description: >- Decimal places used to round monetary amounts in the document currency. Derived server-side from the business rule (0 for zero-decimal currencies such as CLP/COP/XOF/GMD, 2 otherwise); feed it to the client calc-engine CalcContext instead of hardcoding a table. example: 2 readOnly: true currencyDecimalsSystem: type: integer format: int32 description: Decimal places of the system / home currency (same derivation rule as currencyDecimals) example: 2 readOnly: true exchangeRate: type: number description: Exchange rate to system currency example: 1 minimum: 0 grossAmountSystem: type: number description: Gross amount in system currency readOnly: true discountAmountSystem: type: number description: Discount amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT amount in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true roundingMode: type: string description: Rounding mode applied readOnly: true relationConcept: type: string description: Inter-document relation concept readOnly: true relationType: type: string description: Inter-document relation type readOnly: true linkableQuantity: type: number description: Quantity still available for linking readOnly: true relationQuantity: type: number description: Quantity already linked readOnly: true totalApprovals: type: integer format: int32 description: Number of required approvals readOnly: true validatedApprovals: type: integer format: int32 description: Number of validated approvals readOnly: true relatedDocuments: type: array description: Documents related to this one items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true attachments: type: array description: File attachments items: $ref: '#/components/schemas/AttachmentRef' readOnly: true createdBy: type: string description: User who created the document readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: User who last modified the document readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business timezone offset) readOnly: true sourceSystem: type: string description: System that originated this document readOnly: true sapCode: type: string description: SAP document code readOnly: true lockType: type: string description: Lock type if the document is locked readOnly: true payments: type: array description: Inline payments registered against this document. Use the standalone POST /api/v2/payments to add more after creation. items: $ref: '#/components/schemas/PaymentDocument' lines: type: array description: Sales delivery-note line items items: $ref: '#/components/schemas/SalesDeliveryNoteLineDocument' carrierId: type: integer format: int64 description: Carrier (transportista) ID carrierName: type: string description: Carrier name readOnly: true carrierTaxId: type: string description: Carrier tax ID readOnly: true driverName: type: string description: Driver name vehicleId: type: integer format: int64 description: Vehicle ID vehiclePlate: type: string description: Vehicle license plate vehicleModel: type: string description: Vehicle model readOnly: true shipmentNumber: type: string description: Shipment / tracking number transportNote: type: boolean description: Whether this delivery note is also a transport note loadingNote: type: boolean description: Whether this is a loading note (albar├ín de carga) quickReceive: type: boolean description: Whether the goods were received via the express receive flow readOnly: true tareWeight: type: integer format: int32 description: Tare weight (packaging) grossWeight: type: integer format: int32 description: Gross weight (goods + packaging) netWeight: type: integer format: int32 description: Net weight (goods only) required: - counterpartyId - warehouseId SalesDeliveryNoteLineDocument: type: object description: Sales delivery-note line ÔÇö read/write document. properties: id: type: integer format: int64 description: Line ID ÔÇö null on create for new lines, present to update an existing line lineNumber: type: integer format: int32 description: Sequential line number within the document readOnly: true productId: type: integer format: int64 description: Product ID (required on create) example: 1024 productName: type: string description: Line name shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived name. productDescription: type: string description: Line description shown on the document. Server-derived from the product; a non-null value OVERRIDES it (permission EDITAR_DESCART_*), null keeps the product-derived description. extendedDescription: type: string description: Additional line description packs: type: number description: Number of packs (unidades por pack ya resueltas) example: 2 batch: type: string description: Batch / lot text example: L-2026-03 expirationDate: type: string description: Batch expiration date (ISO 8601 date) example: '2027-06-30' unitPrice: type: number description: Unit price before discounts. Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA, WebPos Panama) are enforced server-side. example: 49.9 quantity: type: number description: >- Quantity (required on create). Negative values are legal on credit notes / refund lines; document-type and company-mode sign rules (e.g. OLA credit notes require quantity <= -1) are enforced server-side. example: 2 grossAmount: type: number description: Gross amount (qty x price) readOnly: true discountPct: type: number description: Line discount percentage (0-100) example: 10 maximum: 100 minimum: 0 discountAmount: type: number description: Absolute discount amount (alternative to percentage) example: 5 minimum: 0 commercialNetAmount: type: number description: Line net amount BEFORE insurer/customer copayment split. readOnly: true copaymentDiscount: type: number description: Copayment discount (insurance) readOnly: true netAmount: type: number description: Taxable net amount readOnly: true vatTypeId: type: integer format: int64 description: VAT type ID example: 1 vatTypeName: type: string description: VAT type name readOnly: true vatPct: type: number description: VAT percentage readOnly: true vatAmount: type: number description: VAT amount readOnly: true manualVatAmount: type: number description: >- Manual VAT amount override. Input-only intent: when set on a write it replaces the computed line VAT (legacy 'IVA manual'); never returned by GET (read vatAmount instead), so omitting/null leaves the computed VAT untouched. writeOnly: true manualSurchargeAmount: type: number description: 'Manual surcharge amount override (legacy ''RE manual''). Input-only intent: never returned by GET (read surchargeAmount instead).' writeOnly: true surchargeTypeId: type: integer format: int64 description: Surcharge equivalence type ID surchargeTypeName: type: string description: Surcharge type name readOnly: true surchargePct: type: number description: Surcharge percentage readOnly: true surchargeAmount: type: number description: Surcharge amount readOnly: true total: type: number description: Line total (net + VAT + surcharge) readOnly: true commercialTotalAmount: type: number description: Line total (with VAT) BEFORE insurer/customer copayment split. readOnly: true discounts: type: array description: >- Line discount elements (insurer contribution, discount PIN, points redemption) applied AFTER the commercial discount. On writes: null = leave untouched; a list = reconcile (present elements are applied/updated via the pricing engine ÔÇö caps enforced ÔÇö, absent elements are removed). items: $ref: '#/components/schemas/LineDiscountDocument' appliedPriceRule: $ref: '#/components/schemas/AppliedPriceRuleDocument' description: Pricing rule the backend applied to this line (tariff discount, combo or PIN). Explains the commercial discount origin. readOnly: true excludedTariffIds: type: array description: Tariff IDs excluded from automatic pricing on this line (promotion opt-out). The sentinel -1 (exclude PIN) is managed through excludePin instead. items: type: integer format: int64 excludePin: type: boolean description: Exclude the document discount PIN from this line campaignId: type: integer format: int64 description: Campaign / promotion ID campaignName: type: string description: Campaign name readOnly: true grossAmountSystem: type: number description: Gross amount in system currency readOnly: true netAmountSystem: type: number description: Net amount in system currency readOnly: true vatAmountSystem: type: number description: VAT in system currency readOnly: true totalSystem: type: number description: Total in system currency readOnly: true reservedQuantity: type: number description: Reserved stock quantity readOnly: true vatAccountId: type: integer format: int64 description: VAT ledger account ID surchargeAccountId: type: integer format: int64 description: Surcharge equivalence ledger account ID revenueAccountId: type: integer format: int64 description: Revenue ledger account ID relatedDocuments: type: array description: Related documents linked to this line items: $ref: '#/components/schemas/RelatedDocumentRef' readOnly: true opticalOrderId: type: integer format: int64 description: ID of the optical order (encargo) this line belongs to. readOnly: true baseType: type: string description: Base document type enum: - ORDER - DELIVERY_NOTE - INVOICE - QUOTE writeOnly: true baseEntry: type: integer format: int64 description: Base document ID writeOnly: true baseLine: type: integer format: int32 description: Line number in the base document writeOnly: true baseQuantity: type: number description: Quantity to take from the base document line minimum: 0 writeOnly: true required: - productId - quantity ReturnCauseDocument: type: object description: Return cause (CausaDevolucion) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true code: type: integer format: int64 description: Business code (unique, company-scoped). Optional on create ÔÇö the WAR assigns the next sequential value when omitted. example: 1001 name: type: string description: Display name example: Defective product description: type: string description: Description allowsItems: type: boolean description: Whether line items can be added when this return cause is used example: true requiresClaim: type: boolean description: Whether a claim (reclamo) is required for this return cause example: false enabled: type: boolean description: Whether the return cause is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true RangeDocument: type: object description: Range ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö not versioned) readOnly: true code: type: string description: Business code (unique) example: PREMIUM name: type: string description: Display name example: Premium description: type: string description: Description enabled: type: boolean description: Whether the range is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true CustomFieldValueDocument: type: object description: Custom field value entry ÔÇö unified read/write document. properties: customFieldId: type: integer format: int64 description: Stable ID of the custom field (ges_customfield.id). example: 42 apiName: type: string description: API name of the custom field (ges_customfield.nombre). example: color valueType: type: string description: Value type. One of LIBRE, NUMERICO, OPCIONES, COLOR. example: OPCIONES readOnly: true value: type: string description: 'Raw value: text for LIBRE/NUMERICO, option label for OPCIONES/COLOR. On writes, ignored when optionId is provided.' example: Rojo optionId: type: integer format: int64 description: Stable ID of the selected option (ges_customfield_option.id). Only for OPCIONES/COLOR. Has precedence over value on writes. example: 7 optionLabel: type: string description: Display label of the selected option (currently equal to value). readOnly: true optionHex: type: string description: Hex color of the selected option. Only present for COLOR. example: '#FF0000' readOnly: true EntityRef: type: object description: Lightweight reference to a related entity properties: id: type: integer format: int64 description: Entity primary key example: 142 name: type: string description: Human-readable name example: ├ôptica Central ProductDocument: type: object description: Product ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (Modelo is not versioned ÔÇö always null) readOnly: true name: type: string description: Display name example: Ray-Ban Aviator Classic description: type: string description: Internal description modelCode: type: string description: Business model code (unique per company) example: RB-3025 reference: type: string description: Internal reference / SKU prefix alias: type: string description: Display alias cabysCode: type: string description: CAByS code (Costa Rica fiscal classification) externalId: type: string description: External system identifier (sync / import key) enabled: type: boolean description: Whether the product is enabled (defaults to true on create) draft: type: boolean description: Draft flag ÔÇö product not yet published for sales blockType: type: string description: System-level block marker (TipoBloqueo enum name) manufacturable: type: boolean description: Whether the product is manufacturable inventoriable: type: boolean description: Whether stock levels are tracked (defaults to true on create) needsRawMaterial: type: boolean description: Whether the product requires raw material to be produced batchRequired: type: boolean description: Whether the product is sold in batches/lots priceEditable: type: boolean description: Whether prices can be edited on documents online: type: boolean description: Whether the product is published for online sale fabricabilityByVariant: type: boolean description: When true, manufacturability is configured per variant material: type: string description: Material (free text) frameType: type: string description: Frame type (free text, frames only) gender: type: string description: Gender (free text) usefulLifeDays: type: integer format: int32 description: Useful life in days (e.g. for contact lenses) currencyCode: type: string description: Local currency code (ISO 4217) systemCurrencyCode: type: string description: System currency code (ISO 4217) lensIndex: type: number description: Lens index (refractive index) lensStrx: type: string description: Lens STRX category lensMaterial: type: string description: Lens material lensShape: type: string description: Lens shape onlineName: type: string description: Display name shown on online channels shortDescription: type: string description: Short description (HTML allowed) extendedDescription: type: string description: Full extended description (HTML allowed) linkRewrite: type: string description: URL slug used by external storefronts webStockManagementType: type: string description: Web stock-management strategy (TipoGestionStockWeb) webVisibilityType: type: string description: Web visibility strategy (TipoVisibilidadWeb) onlineChannelIds: type: array description: Online channel IDs the product is published to items: type: integer format: int64 companyId: type: integer format: int64 description: Company ID (required on create) example: 1 companyName: type: string description: Company name readOnly: true supplierId: type: integer format: int64 description: Default supplier (Tercero) ID supplierName: type: string description: Default supplier name readOnly: true categoryId: type: integer format: int64 description: Main category ID categoryName: type: string description: Main category name readOnly: true brandId: type: integer format: int64 description: Brand ID brandName: type: string description: Brand name readOnly: true groupId: type: integer format: int64 description: Group ID groupName: type: string description: Group name readOnly: true campaignId: type: integer format: int64 description: Campaign ID campaignName: type: string description: Campaign name readOnly: true collectionId: type: integer format: int64 description: Collection ID collectionName: type: string description: Collection name readOnly: true rangeId: type: integer format: int64 description: Range (gama) ID rangeName: type: string description: Range name readOnly: true itemTypeId: type: integer format: int64 description: Item type (TipoArticulo) ID ÔÇö accounting classification itemTypeName: type: string description: Item type name readOnly: true vatTypeId: type: integer format: int64 description: Default VAT type ID vatTypeName: type: string description: Default VAT type name readOnly: true vatRate: type: number description: Default VAT rate snapshot (percentage) readOnly: true additionalCategoryIds: type: array description: Additional category IDs (besides the main category) ÔÇö input only items: type: integer format: int64 writeOnly: true categories: type: array description: Additional categories (besides the main category) ÔÇö read denormalised items: $ref: '#/components/schemas/EntityRef' readOnly: true defaultVariantId: type: integer format: int64 description: Default variant ID (productoPredeterminado) defaultImageId: type: integer format: int64 description: Default attachment ID (image) readOnly: true caseProductId: type: integer format: int64 description: Frame case product ID (estucheMontura) ÔÇö optical only caseProductName: type: string description: Frame case product name readOnly: true workOrderProductId: type: integer format: int64 description: Work-order companion product ID (productoAniadirOT) ÔÇö optical only workOrderProductName: type: string description: Work-order companion product name readOnly: true temporaryImageIds: type: array description: Temporary image IDs previously returned by POST /api/v2/products/images. Converted into persisted attachments on save. items: type: string writeOnly: true defaultTemporaryImageId: type: string description: Temporary image ID to use as the product's default image. writeOnly: true customFields: type: array description: Product-level custom field values (asociableCon=MODELO). items: $ref: '#/components/schemas/CustomFieldValueDocument' variantCustomFieldIds: type: array description: Custom field IDs declared as columns on every variant items: type: integer format: int64 manufacturingFieldIds: type: array description: Custom field IDs declared as manufacturing fields items: type: integer format: int64 variants: type: array description: Variants belonging to this product items: $ref: '#/components/schemas/ProductVariantDocument' images: type: array description: Product images (attachments) with their public URL items: $ref: '#/components/schemas/ProductImageDocument' readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ProductImageDocument: type: object description: Product image (attachment) ÔÇö read-only. properties: id: type: integer format: int64 description: Attachment ID readOnly: true url: type: string description: Public URL of the image readOnly: true name: type: string description: Image name readOnly: true ProductVariantDocument: type: object description: Product variant ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Variant ID ÔÇö null on create for new variants, present to update an existing one (Producto.id) example: 10245 version: type: integer format: int32 description: Optimistic lock version readOnly: true barCode: type: string description: Bar code (EAN/UPC, must be unique within the company) gtin: type: string description: Global Trade Item Number reference: type: string description: Internal reference / SKU code description: type: string description: Description shown on documents supplierDescription: type: string description: Free-text description used by the supplier color: type: string description: Color rod: type: number description: Rod / arm length in millimetres (frames only) bridge: type: number description: Bridge size in millimetres (frames only) horizontalDiameter: type: integer format: int32 description: Horizontal lens diameter (frames) verticalDiameter: type: integer format: int32 description: Vertical lens diameter (frames) usefulLifeDays: type: integer format: int32 description: Useful life in days (e.g. for contact lenses) enabled: type: boolean description: Whether the variant is enabled (defaults to true on create) draft: type: boolean description: Draft flag ÔÇö variant not yet published discontinued: type: boolean description: Whether the variant is discontinued batch: type: boolean description: Whether the variant is sold as a batch / lot inventoriable: type: boolean description: Whether the variant counts toward inventory levels readOnly: true priceEditable: type: boolean description: Whether the variant requires special permission to be priced readOnly: true purchasePriceNet: type: number description: Purchase price (net, before VAT) purchasePriceGross: type: number description: Purchase price (gross, with VAT) salePriceNet: type: number description: Sale price (net, before VAT) salePriceGross: type: number description: Sale price (gross, with VAT) factor: type: number description: Multiplicative factor used to derive sale from purchase price margin: type: number description: Commercial margin (percentage) vatTypeId: type: integer format: int64 description: VAT type ID vatRate: type: number description: VAT rate snapshot (percentage) readOnly: true purchasePriceSystem: type: number description: Purchase price (net) in system currency readOnly: true salePriceSystem: type: number description: Sale price (net) in system currency readOnly: true salePriceGrossSystem: type: number description: Sale price (gross) in system currency readOnly: true exchangeRate: type: number description: Exchange rate used readOnly: true packQuantity: type: number description: Quantity of base units in a single pack/box (default 1) packProductId: type: integer format: int64 description: Pack/box parent product (nullable) temporaryImageIds: type: array description: Temporary image IDs previously returned by POST /api/v2/products/images. Converted into persisted attachments on save. items: type: string writeOnly: true defaultTemporaryImageId: type: string description: Temporary image ID to use as this variant's default image. writeOnly: true defaultImageId: type: integer format: int64 description: Default attachment ID for this variant (image). customFields: type: array description: Variant-level custom field values (asociableCon=PRODUCTO). Same shape across every v2 entity. null = no change, [] = clear all. items: $ref: '#/components/schemas/CustomFieldValueDocument' stockLevels: type: array description: Stock levels per branch. items: $ref: '#/components/schemas/ProductVariantStockDto' readOnly: true stockMinimums: type: array description: Per-branch minimum stock to set. Branches not listed are left untouched. items: $ref: '#/components/schemas/ProductVariantStockMinimumDto' writeOnly: true supplierPrices: type: array description: Supplier-specific purchase prices and references. items: $ref: '#/components/schemas/ProductVariantSupplierPriceDto' readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp. readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp. readOnly: true ProductVariantStockDto: type: object description: Stock level for a single branch properties: warehouseId: type: integer format: int64 description: Warehouse / store ID warehouseName: type: string description: Warehouse / store name currentQuantity: type: number description: Current quantity on hand reservedQuantity: type: number description: Reserved quantity (already committed but not delivered) minimumStock: type: number description: Configured minimum stock level ProductVariantStockMinimumDto: type: object description: Per-branch minimum stock for a variant properties: warehouseId: type: integer format: int64 description: Warehouse / store ID minimumStock: type: number description: Minimum stock to keep on hand ProductVariantSupplierPriceDto: type: object description: Supplier-specific purchase price for a variant properties: id: type: integer format: int64 description: Supplier-price row ID supplierId: type: integer format: int64 description: Supplier (Tercero) ID supplierName: type: string description: Supplier name reference: type: string description: Supplier's reference / SKU for this variant price: type: number description: Net purchase price (before VAT) lastPurchaseDate: type: string description: Date this price was last updated by the supplier (ISO 8601) PriceListBranchScheduleDocument: type: object description: Branch activation window for a price list. properties: id: type: integer format: int64 description: Primary key readOnly: true warehouseId: type: integer format: int64 description: Branch (sucursal) ID example: 3 warehouseName: type: string description: Branch name readOnly: true fromDate: type: string description: Active from this calendar day (yyyy-MM-dd) example: '2026-01-01' toDate: type: string description: Active until this calendar day (yyyy-MM-dd) example: '2026-12-31' fromTime: type: string description: Daily window start (HH:mm) example: '00:00' toTime: type: string description: Daily window end (HH:mm) example: '23:59' monday: type: boolean description: Active on Mondays (defaults to true) tuesday: type: boolean description: Active on Tuesdays (defaults to true) wednesday: type: boolean description: Active on Wednesdays (defaults to true) thursday: type: boolean description: Active on Thursdays (defaults to true) friday: type: boolean description: Active on Fridays (defaults to true) saturday: type: boolean description: Active on Saturdays (defaults to true) sunday: type: boolean description: Active on Sundays (defaults to true) PriceListDocument: type: object description: Price list (tarifa) ÔÇö unified read/write document. Persisted in draft mode via POST /price-lists/new; PUT finalises the draft. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (price lists are not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (prefixed with the company code) example: GE0001 name: type: string description: Display name example: Tarifa base 2026 description: type: string description: Description priceListType: type: string description: Price list kind (TipoTarifa). Immutable after creation. enum: - TB - TBF - DTO - COM example: TB enabled: type: boolean description: Whether the record is enabled example: true active: type: boolean description: Whether the price list is active (applies to documents) example: true draft: type: boolean description: Draft flag. Set by POST /price-lists/new; cleared by the server on PUT. readOnly: true forSales: type: boolean description: true = sales price list (emitido); false = purchase side. Immutable after creation. example: true stackable: type: boolean description: 'COM only: the combo can be applied more than once in the same document' appliesOnPartialPayment: type: boolean description: 'COM only: the combo also applies when the document is partially paid' requiresValues: type: boolean description: 'TB only: filling a value for every product is mandatory' usesProductBaseValue: type: boolean description: 'TBF only: derive from the product master price instead of a source price list. When true the server clears sourcePriceListId.' priceSourceType: type: string description: 'TBF + usesProductBaseValue: which product master price to use' enum: - PV - PC example: PV blockType: type: string description: Integration lock type (server managed) readOnly: true effectiveFrom: type: string description: Validity start (ISO 8601 with business offset) effectiveTo: type: string description: Validity end (ISO 8601 with business offset) currencyCode: type: string description: ISO 4217 currency code overriding the company local currency example: EUR purchaseConditionsCount: type: integer format: int32 description: Number of purchase combo conditions (server computed) readOnly: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true sourcePriceListId: type: integer format: int64 description: 'TBF only: source price list this one is derived from (TB or TBF)' sourcePriceListName: type: string description: Source price list name readOnly: true paymentMethodIds: type: array description: 'COM only: payment methods that must settle the document for the combo to apply' items: type: integer format: int64 cardTypes: type: array description: 'COM only: card kinds (TipoTarjetasEcuador enum names) that trigger the combo' example: - VISA - MASTERCARD items: type: string branchSchedules: type: array description: Branches where this price list is active, with optional date/time/weekday windows. null = leave untouched; [] = clear; non-empty = full replacement. items: $ref: '#/components/schemas/PriceListBranchScheduleDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true PriceListEntryDocument: type: object description: Price list entry (product price or discount rule). properties: id: type: integer format: int64 description: Primary key readOnly: true priceListId: type: integer format: int64 description: Owning price list ID readOnly: true priceListType: type: string description: Price list kind copied from the owning price list enum: - TB - TBF - DTO - COM readOnly: true productId: type: integer format: int64 description: Product (variant/SKU) this entry prices. Null for discount rules. productName: type: string description: Product description readOnly: true productReference: type: string description: Product reference readOnly: true reference: type: string description: Free-text reference stored on the entry price: type: number description: Final unit price (used when finalPrice=true) discountPercent: type: number description: Discount percentage (used when finalPrice=false) factor: type: number description: 'TBF only: multiplier applied on the source price' finalPrice: type: boolean description: true = price is a final unit price; false = discountPercent applies vatIncluded: type: boolean description: The stored price includes VAT forSales: type: boolean description: true = sales entry; false = purchase entry (copied from the price list) readOnly: true comboConditionId: type: integer format: int64 description: Combo condition this entry belongs to (COM price lists) ruleOrder: type: integer format: int32 description: Discount-rule order. Null for plain product entries. readOnly: true categoryId: type: integer format: int64 description: 'Rule scope: category' categoryName: type: string description: Category name readOnly: true brandId: type: integer format: int64 description: 'Rule scope: brand' brandName: type: string description: Brand name readOnly: true groupId: type: integer format: int64 description: 'Rule scope: group' groupName: type: string description: Group name readOnly: true campaignId: type: integer format: int64 description: 'Rule scope: campaign' campaignName: type: string description: Campaign name readOnly: true counterpartyId: type: integer format: int64 description: Customer-specific price entry (tercero) lastModifiedAt: type: string description: Last modification timestamp readOnly: true PriceListComboConditionDocument: type: object description: Combo condition (purchase requirement or applied discount) of a COM price list. properties: id: type: integer format: int64 description: Primary key readOnly: true priceListId: type: integer format: int64 description: Owning price list ID readOnly: true name: type: string description: Condition name example: Art├¡culo 1 purchaseCondition: type: boolean description: true = purchase requirement; false = applied discount. Immutable after creation. quantity: type: number description: Units required (purchase side) or discounted (sale side) price: type: number description: Final unit price applied (used when finalPrice=true) discountPercent: type: number description: Discount percentage applied (used when finalPrice=false) finalPrice: type: boolean description: true = price is a final unit price; false = discountPercent applies vatIncluded: type: boolean description: The stored price includes VAT PaymentTermDocument: type: object description: Payment terms (CondicionPago) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (CondicionPago is not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique per company) example: 30-60-90 name: type: string description: Display name example: 30/60/90 d├¡as description: type: string description: Description printText: type: string description: Free text printed on documents that use these terms instalmentCount: type: integer format: int32 description: Number of instalments (due dates) example: 3 firstDueDays: type: integer format: int32 description: Days from the document date to the first due date example: 30 intervalDays: type: integer format: int32 description: Days between consecutive instalments example: 30 paymentDay1: type: integer format: int32 description: Preferred day of month for payment (1-31), optional example: 5 paymentDay2: type: integer format: int32 description: Alternative preferred day of month for payment (1-31), must be greater than paymentDay1 when both are set example: 20 calendarDays: type: boolean description: true = calendar (natural) days, false = business days example: true useNextPaymentDay: type: boolean description: 'When adjusting to paymentDay1/paymentDay2: true = move to the next payment day, false = move to the closest payment day' example: true bankName: type: string description: Bank entity name bankAccount: type: string description: Bank account (IBAN) enabled: type: boolean description: Whether the payment terms are enabled (defaults to true on create) example: true blockType: type: string description: Document blocking state driven by fiscal-sync integrations (SII/SAT/ÔǪ); server-managed readOnly: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true paymentMethodId: type: integer format: int64 description: Payment method ID (FormaDePago) example: 3 paymentMethodName: type: string description: Payment method name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true AssociatedAccountDocument: type: object description: Payment method ledger account mapping for one company (con_cuentas_tercero) properties: id: type: integer format: int64 description: Row ID example: 33 readOnly: true companyId: type: integer format: int64 description: Company ID this ledger mapping applies to. Must belong to the owner company or its consolidated group when the group shares payment methods. example: 1 companyName: type: string description: Company name readOnly: true accountId: type: integer format: int64 description: Main ledger account (CuentaContable) ID example: 10045 accountCode: type: string description: Ledger account code readOnly: true accountName: type: string description: Ledger account name readOnly: true PaymentMethodDocument: type: object description: Payment method (FormaDePago) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 3 readOnly: true version: type: integer format: int32 description: Optimistic lock version (FormaDePago is not versioned ÔÇö always null) readOnly: true code: type: integer format: int64 description: Numeric business code, unique across the tenant. Auto-generated from the company code sequence when omitted on create. example: 10000034 name: type: string description: Display name example: Transferencia bancaria description: type: string description: Internal description enabled: type: boolean description: Whether the payment method is enabled (defaults to true on create) example: true enabledForRefunds: type: boolean description: Whether the payment method can be picked when managing a refund example: true excludeFromCashClose: type: boolean description: Exclude payments made with this method from the cash-register close (also skips the closed-register validation) example: false internalGesvision: type: boolean description: Internal Gesvision payment method (skipped / treated specially by external sync integrations) example: false paymentKind: type: string description: >- Payment kind (TipoFormaDePago): E=Efectivo, T=Tarjeta, V=Vales, C=Cheques/Talones, O=Otros, R=Retenciones, I=Pago en divisas con impuesto, P=Cr├®dito, D=Tarjeta d├®bito, B=Transferencia bancaria, G=Giro bancario. Required. enum: - E - T - V - C - O - R - I - P - D - B - G example: B collectionKind: type: string description: 'Payment purpose (TipoCobro): CP=Cobro/Pago, RI=Regularizaci├│n interna' enum: - CP - RI example: CP cardTerminal: type: string description: 'Card terminal integration (TipoDatafono): MD=Medianet, DF=DataFast, DE=Deuna, MN=Manual. Only valid for card kinds (T, D).' enum: - MD - DF - DE - MN example: MD webPosPaymentKind: type: string description: Panam├í WebPOS fiscal payment kind (TipoFormaDePagoWebPos) enum: - E - TC - TD - C - O - G - NC - CR - O2 example: TC sriPaymentMethod: type: string description: SRI Ecuador payment method code (TipoFormaPagoSRI T1..T21) enum: - T1 - T2 - T3 - T4 - T5 - T6 - T7 - T8 - T9 - T10 - T11 - T12 - T13 - T14 - T15 - T16 - T17 - T18 - T19 - T20 - T21 example: T20 olaCardType: type: string description: SAP OLA credit-card mapping (TipoTarjetaCredito). Only valid for card kinds (T, D). enum: - T1 - T2 - T3 - T4 - T5 - T6 - T7 - T8 - T9 - T10 - T11 - T12 - T13 - T14 - T15 - T16 - T17 - T18 - T19 - T20 - T21 - T22 - T23 - T24 - T30 example: T9 sapCrPaymentMethod: type: string description: 'SAP Costa Rica payment medium (MedioPago): RT=Recaudado por terceros, SM=Sinpe M├│vil, PD=Plataforma digital, O=Otros' enum: - RT - SM - PD - O example: SM satPaymentMethod: type: string description: >- SAT M├®xico c_FormaPago mapping (CFormaPago enum name). VALUE_1=01 Efectivo, VALUE_2=02 Cheque nominativo, VALUE_3=03 Transferencia, VALUE_4=04 Tarjeta de cr├®dito, VALUE_5=05 Monedero electr├│nico, VALUE_6=06 Dinero electr├│nico, VALUE_7=08 Vales de despensa, VALUE_18=28 Tarjeta de d├®bito, VALUE_22=99 Por definir, ÔǪ enum: - VALUE_1 - VALUE_2 - VALUE_3 - VALUE_4 - VALUE_5 - VALUE_6 - VALUE_7 - VALUE_8 - VALUE_9 - VALUE_10 - VALUE_11 - VALUE_12 - VALUE_13 - VALUE_14 - VALUE_15 - VALUE_16 - VALUE_17 - VALUE_18 - VALUE_19 - VALUE_20 - VALUE_21 - VALUE_22 example: VALUE_3 requiresChange: type: boolean description: Show the tendered/change calculation when collecting. Only valid for cash kinds (E, I). example: false bankMovement: type: boolean description: Payment moves through a bank account (drives the ledger fallback to the bank account and requires an accounting date). Not valid for cash (E) or vouchers (V). example: true automaticAccountingDate: type: boolean description: Automatically assign the accounting date when posting the payment to the ledger example: true voucher: type: boolean description: The method issues/redeems store-credit vouchers. Only valid for the voucher kind (V); requires voucherValidityDays. example: false voucherValidityDays: type: integer format: int32 description: Validity in days of the vouchers issued with this method. Required when voucher=true, forbidden otherwise. example: 365 promissoryNote: type: boolean description: 'Promissory note (pagar├®): enables note printing and due-date based accounting. Only valid for kinds C, B, G, O, P.' example: false alwaysRefundable: type: boolean description: On credit notes / claims, force the refund with this same payment method for the full amount example: false cashKeeper: type: boolean description: CashKeeper smart cash-drawer integration. Only valid for cash (E); activates when the branch also has a CashKeeper terminal. example: false postToLedger: type: boolean description: Post payments made with this method to the accounting ledger example: true requiresValidation: type: boolean description: Payments made with this method require manual validation in the payments listing example: false askInstalments: type: boolean description: Ask for the number of instalments when collecting (deferred / financed payments). Only valid for kinds O, P, T, D. example: false subscription: type: boolean description: Mark orders paid with this method as subscriptions (recurring payments) example: false usableForIncoming: type: boolean description: Available for incoming documents (sales / receipts). At least one of usableForIncoming / usableForOutgoing must be true. example: true usableForOutgoing: type: boolean description: Available for outgoing documents (purchases / payments). At least one of usableForIncoming / usableForOutgoing must be true. example: false taxPct: type: number description: Surcharge percentage applied on foreign-currency payments (IGTF). Only valid (> 0) for kind I. example: 3 appliesPaymentTax: type: boolean description: >- Whether payments with this method accrue the payment tax (IGTF): derived server-side (true when paymentKind is I). When true the client can preview the quota as taxPct% over the outstanding base before saving. example: true readOnly: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true associatedAccounts: type: array description: 'Per-company ledger account mapping (con_cuentas_tercero). Write semantics: null leaves the collection untouched, [] clears it, a non-empty list replaces every row.' items: $ref: '#/components/schemas/AssociatedAccountDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true OriginTypeDocument: type: object description: Claim origin type (ReclamoTipoOrigen) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true name: type: string description: Display name example: Customer call description: type: string description: Description enabled: type: boolean description: Whether the origin type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true EyePrescriptionDocument: type: object description: Optical prescription data for a single eye ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key of the underlying prescription record. null on create for new rows; present to update existing ones. eye: type: string description: Which eye this prescription applies to enum: - RIGHT - LEFT example: RIGHT lensType: type: string description: Lens type enum: - FAR - NEAR - INTERMEDIATE - TORIC - MULTIFOCAL - BIFOCAL - PROGRESSIVE - OCCUPATIONAL crystalType: type: string description: Crystal / lens material type code (legacy TipoCristal) sphere: type: number description: Sphere (esfera) in diopters cylinder: type: number description: Cylinder (cilindro) in diopters axis: type: number description: Axis (eje) in degrees, 0-180 addition: type: number description: Addition for near vision (adici├│n) in diopters near: type: number description: Near prescription value (cerca) in diopters prism: type: number description: Prism (prisma) in prism diopters base: type: string description: Prism base direction (UP, DOWN, IN, OUT or compound) diameter: type: number description: Lens diameter (di├ímetro) in millimeters baseCurve: type: number description: Base curve (curva base) in millimeters height: type: number description: Fitting height (altura de montaje) in millimeters nearMonocularPd: type: number description: Near monocular pupillary distance (DNPC) in millimeters farMonocularPd: type: number description: Far monocular pupillary distance (DNPL) in millimeters lotNumber: type: string description: Manufacturing lot number applied to the lens invima: type: string description: INVIMA registry code (Colombia health regulator) OpticalAddOnRef: type: object description: Reference to a lens add-on attached to the order properties: productId: type: integer format: int64 description: Product primary key productName: type: string description: Product display name addOnType: type: string description: Add-on category code enum: - COLORATION - TREATMENT - SUPPLEMENT sourceLineId: type: integer format: int64 description: Line item ID inside the parent document OpticalOrderDocument: type: object description: Optical order ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Optical order primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true documentType: type: string description: Document type discriminator example: OPTICAL_ORDER readOnly: true series: type: string description: Series prefix example: OT number: type: integer format: int64 description: Sequential number readOnly: true code: type: string description: Full document code (series + zero-padded number) readOnly: true documentStatusId: type: integer format: int64 description: User-defined document status ID (Kanban) documentStatusName: type: string description: User-defined document status name readOnly: true assembled: type: boolean description: 'Workshop: lens assembled into the frame' rawMaterialSelected: type: boolean description: 'Workshop: raw material has been selected' bevelSent: type: boolean description: 'Workshop: lens edging sent to the lab' requestSupplier: type: boolean description: Whether the order must be sourced from a supplier ownManufacturing: type: boolean description: Whether the lenses are manufactured in-house ownFrame: type: boolean description: Whether the patient brought their own frame contactLenses: type: boolean description: Whether the order is for contact lenses (vs. glasses) sameLensBothEyes: type: boolean description: Whether both eyes share the same lens model useRxForContactology: type: boolean description: Whether the refraction prescription (RX) is also used for contactology documentDate: type: string description: Order date (ISO 8601 with business timezone offset). Defaults to current server timestamp on create if omitted. example: '2026-03-15T10:30:00+01:00' firstPrintDate: type: string description: Date the order was first printed readOnly: true customerId: type: integer format: int64 description: Patient (Tercero) ID ÔÇö required on create customerName: type: string description: Patient name readOnly: true patientInitials: type: string description: Two-letter patient initials shown on workshop labels companyId: type: integer format: int64 description: Issuing company ID ÔÇö required on create example: 1 companyName: type: string description: Issuing company name readOnly: true warehouseId: type: integer format: int64 description: Branch / store ID ÔÇö required on create example: 4 warehouseName: type: string description: Branch / store name readOnly: true orderTypeId: type: integer format: int64 description: User-defined order type ID (TipoDocumento) orderTypeName: type: string description: User-defined order type name readOnly: true optometricExamId: type: integer format: int64 description: Optometric exam ID providing the refraction contactLensExamId: type: integer format: int64 description: Contact lens fitting exam ID (LentesDefinitivas) customerOrderId: type: integer format: int64 description: Customer sales order ID this optical order originated from invoiceId: type: integer format: int64 description: Sales invoice ID this optical order is attached to supplierOrderId: type: integer format: int64 description: Supplier purchase order ID productionOrderId: type: integer format: int64 description: Production order ID (orden de fabricaci├│n) frameShipmentTransferId: type: integer format: int64 description: Frame shipment transfer ID (traspaso env├¡o montura) readOnly: true bevelledLensTransferId: type: integer format: int64 description: Bevelled lens transfer ID (traspaso lentes biselados) readOnly: true finishedLensTransferId: type: integer format: int64 description: Finished lens transfer ID (traspaso lentes terminados) readOnly: true lastTraceId: type: integer format: int64 description: Last trace (OMA) record ID readOnly: true frameProductId: type: integer format: int64 description: Frame product ID (montura) frameProductName: type: string description: Frame product name readOnly: true frameType: type: string description: Frame type code (CO=full, AA=rimless, SA=semi-rimless) enum: - CO - AA - SA frameHorizontal: type: number description: Eye-size A ÔÇö horizontal lens box width frameVertical: type: number description: Eye-size B ÔÇö vertical lens box height frameBridge: type: number description: Bridge / DBL frameBiggestDiameter: type: number description: Largest diameter frameEffectiveDiameter: type: number description: Effective diameter used to choose the lens blank frameMechanicalDistance: type: number description: Mechanical distance pantoscopicAngle: type: number panoramicAngle: type: number vertexDistance: type: number nearWorkingDistance: type: number eyeRotationCenter: type: number pupillaryDistance: type: number medianDistance: type: number frameFit: type: number cCode: type: number heightRightEye: type: number heightLeftEye: type: number edgeThickness: type: number specialBase: type: number maxDecentrationRightEye: type: number maxDecentrationLeftEye: type: number dominantEye: type: string description: Dominant eye enum: - RIGHT - LEFT - NONE nvb: type: string description: NVB (near visual behaviour) code rightLensProductId: type: integer format: int64 description: Lens product ID ÔÇö right eye (OD) rightLensProductName: type: string description: Lens product name ÔÇö right eye readOnly: true leftLensProductId: type: integer format: int64 description: Lens product ID ÔÇö left eye (OI) leftLensProductName: type: string description: Lens product name ÔÇö left eye readOnly: true recommendedLensTypeRightEye: type: string description: Recommended lens type for the right eye enum: - FAR - NEAR - INTERMEDIATE - TORIC - MULTIFOCAL - BIFOCAL - PROGRESSIVE - OCCUPATIONAL recommendedLensTypeLeftEye: type: string description: Recommended lens type for the left eye enum: - FAR - NEAR - INTERMEDIATE - TORIC - MULTIFOCAL - BIFOCAL - PROGRESSIVE - OCCUPATIONAL rawMaterialRightEyeProductId: type: integer format: int64 description: Raw material product ID for the right-eye lens rawMaterialLeftEyeProductId: type: integer format: int64 description: Raw material product ID for the left-eye lens rightEye: $ref: '#/components/schemas/EyePrescriptionDocument' description: Prescription data for the right eye (OD) leftEye: $ref: '#/components/schemas/EyePrescriptionDocument' description: Prescription data for the left eye (OI) rightEyeColorationProductId: type: integer format: int64 description: Tint / coloration product ID (right-eye lens) writeOnly: true leftEyeColorationProductId: type: integer format: int64 description: Tint / coloration product ID (left-eye lens) writeOnly: true rightEyeTreatmentProductId: type: integer format: int64 description: Treatment product ID (right-eye lens) writeOnly: true leftEyeTreatmentProductId: type: integer format: int64 description: Treatment product ID (left-eye lens) writeOnly: true rightEyeSupplementProductIds: type: array description: Supplement product IDs (right-eye lens) items: type: integer format: int64 writeOnly: true leftEyeSupplementProductIds: type: array description: Supplement product IDs (left-eye lens) items: type: integer format: int64 writeOnly: true rightEyeColoration: $ref: '#/components/schemas/OpticalAddOnRef' description: Resolved tint / coloration (right-eye) readOnly: true leftEyeColoration: $ref: '#/components/schemas/OpticalAddOnRef' description: Resolved tint / coloration (left-eye) readOnly: true rightEyeTreatment: $ref: '#/components/schemas/OpticalAddOnRef' description: Resolved treatment (right-eye) readOnly: true leftEyeTreatment: $ref: '#/components/schemas/OpticalAddOnRef' description: Resolved treatment (left-eye) readOnly: true rightEyeSupplements: type: array description: Resolved supplements (right-eye) items: $ref: '#/components/schemas/OpticalAddOnRef' readOnly: true leftEyeSupplements: type: array description: Resolved supplements (left-eye) items: $ref: '#/components/schemas/OpticalAddOnRef' readOnly: true internalRef: type: string description: Internal reference code supplier: type: string description: Supplier identifier text used by the lab notes: type: string description: Free-text notes shown to the workshop notificationsSent: type: integer format: int32 description: Number of patient notifications already sent readOnly: true notifyPatient: type: boolean description: Whether patient notifications are enabled createdBy: type: string description: User who created the optical order readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: User who last modified the optical order readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true sourceSystem: type: string description: System that originated this optical order readOnly: true ccode: type: number NoteDocument: type: object description: A polymorphic note attachable to any owner entity (customer, customer profile, ...). properties: id: type: integer format: int64 description: Primary key example: 101 readOnly: true version: type: integer format: int32 description: Optimistic lock version (Nota is not versioned ÔÇö always null) readOnly: true name: type: string description: Short title (maps {@code Nota.nombre}). Optional. description: type: string description: Note body (maps {@code Nota.descripcion}). example: Cliente con condiciones especiales de credito alert: type: boolean description: Alert flag (maps {@code Nota.alerta}). example: false categoryKey: type: string description: Category catalog key. categoryName: type: string description: Category display name readOnly: true categoryColor: type: string description: Category colour token for the UI readOnly: true reminderAt: type: string description: Reminder datetime, ISO 8601 with business timezone offset. Nullable. example: '2026-06-01T09:00:00+02:00' ownerType: type: string description: 'Owner resource key: customers | customer-profiles | ...' enum: - customers - customer-profiles example: customer-profiles ownerId: type: integer format: int64 description: Owner entity ID ({@code tercero_id} or {@code perfil_cliente_id}) example: 42 ownerName: type: string description: Owner display name example: Particular readOnly: true employeeId: type: integer format: int64 description: Author employee ID (maps {@code Nota.trabajador_id}) example: 7 employeeName: type: string description: Author employee display name example: Maria Garcia readOnly: true createdBy: type: string description: User that created the record example: admin readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) example: '2026-05-19T10:30:00+02:00' readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true LoyaltyWalletDocument: type: object description: Loyalty points wallet (CarteraPuntos) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (CarteraPuntos is not versioned ÔÇö always null). readOnly: true code: type: string description: Card number / business code (unique within the company). example: '1000024' name: type: string description: Display name of the card. example: Gold Card description: type: string description: Optional description. enabled: type: boolean description: Whether the card is enabled. example: true companyId: type: integer format: int64 description: Company identifier. example: 1 companyName: type: string description: Company display name. readOnly: true counterpartyAccountId: type: integer format: int64 description: Owner customer (tercero_predefinido_id). example: 501 counterpartyAccountName: type: string description: Owner customer display name. readOnly: true pointsBalance: type: number description: Current available points balance. readOnly: true monetaryValue: type: number description: Current monetary value of the available points according to the company's loyalty configuration. readOnly: true pointOperations: type: array description: >- Manual points movements to apply on create or update. Each entry follows the same shape as `POST /loyalty-wallets/{id}/change-points`. On update, null or an empty list leaves the ledger untouched. On create, when omitted, a positive `pointsBalance` still seeds a single manual ADD for backward compatibility. items: $ref: '#/components/schemas/PointsChangeDocument' writeOnly: true members: type: array description: Customers currently sharing this points card. null = no change on update; [] = clear all; non-empty list = full replacement. items: $ref: '#/components/schemas/LoyaltyWalletMemberDocument' readOnly: true createdBy: type: string description: User that created the record. readOnly: true createdAt: type: string description: Creation timestamp (ISO-8601 with business timezone). readOnly: true lastModifiedBy: type: string description: Last user that modified the record. readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO-8601 with business timezone). readOnly: true LoyaltyWalletMemberDocument: type: object description: Customer linked to a loyalty wallet. properties: customerAccountId: type: integer format: int64 description: Customer (Tercero) identifier. customerAccountName: type: string description: Customer display name. readOnly: true customerOwner: type: boolean description: Whether this customer is the owner of the wallet (tercero_predefinido_id). readOnly: true PointsChangeDocument: type: object description: Manual points change command for a loyalty wallet. properties: points: type: number description: Number of points to modify. example: 150 date: type: string description: Business date of the operation. If omitted, the server uses the current business date. example: '2026-06-30T10:15:00+02:00' type: type: string description: Transaction type (TipoPuntosFidelizacion). Defaults to M (manual) when omitted. Manual change-points only accepts M. enum: - W - C - E - M - D example: M operation: type: string description: Operation to perform over the current balance. enum: - ADD - REMOVE example: ADD concept: type: string description: Concept or reason entered by the user for the manual adjustment. example: Compensaci├│n por incidencia required: - operation - points LabelFormatFavoriteRequest: type: object description: Toggle the current user's favourite flag for a label format. properties: favorite: type: boolean description: Whether the format should be marked as a favourite example: true LabelFormatDocument: type: object description: Product-label format available for printing (die-cut sheet, continuous roll or Zebra ZPL). properties: code: type: string description: Stable format code (primary key of the catalog) example: punched-3x8 readOnly: true name: type: string description: Human-readable label example: 3x8 readOnly: true shape: type: string description: Geometric shape enum: - RECTANGULAR example: RECTANGULAR readOnly: true material: type: string description: Physical media enum: - PUNCHED - CONTINUOUS example: PUNCHED readOnly: true medium: type: string description: Output medium produced when rendering enum: - PDF - ZEBRA_ZPL example: PDF readOnly: true widthMm: type: number description: Per-label width in millimetres (continuous/Zebra formats only; null for die-cut grids) example: 60 readOnly: true heightMm: type: number description: Per-label height in millimetres (continuous/Zebra formats only; null for die-cut grids) example: 35 readOnly: true labelsPerSheet: type: integer format: int32 description: Labels per sheet (columns x rows for die-cut; 1 for continuous/Zebra) example: 24 readOnly: true thumbnailUrl: type: string description: Relative URL of the format thumbnail image (PNG) example: /api/v2/label-formats/punched-3x8/thumbnail readOnly: true supportsBarcode: type: boolean description: Whether the format renders a barcode example: true readOnly: true supportsFreeField: type: boolean description: Whether the format supports a free footer field (pie de etiqueta) example: true readOnly: true favorite: type: boolean description: Whether the current user has marked this format as a favourite example: false JournalEntryDocument: type: object description: Accounting journal entry (Asiento) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (Asiento is not versioned ÔÇö always null) readOnly: true code: type: string description: 'Formatted code: {series}/{number padded to 6 digits}' example: AS/000123 readOnly: true series: type: string description: Numbering series example: AS entryNumber: type: integer format: int64 description: Sequential entry number within the series readOnly: true accountingDate: type: string description: Accounting date (ISO 8601 calendar day or datetime with business offset) example: '2026-07-10' fiscalYear: type: string description: Fiscal year (4-digit string) example: '2026' name: type: string description: Display name description: type: string description: Description enabled: type: boolean description: Whether the entry is enabled example: true draft: type: boolean description: Draft entry (not yet posted / numbered) example: true companyId: type: integer format: int64 description: Owning company ID example: 1 companyName: type: string description: Owning company name readOnly: true activityId: type: integer format: int64 description: Header activity ID example: 1 activityName: type: string description: Header activity name readOnly: true accountingBook: type: integer format: int32 description: 'Accounting book: 1, 2 or 3 (both books)' example: 1 entryType: type: string description: Entry type ({@code TipoAsiento}). Served by {@code GET /api/v2/catalogs/entryType}. enum: - ASI - FAC - NOM - COBRO - BANCO - TICKET - CAJA - VALEC - APE - REG - CIE - INM example: ASI predefinedDocument: type: boolean description: Predefined document template flag readOnly: true lockType: type: string description: Lock type readOnly: true modified: type: boolean description: Whether the entry was modified after SAP sync readOnly: true balanced: type: boolean description: Whether debit and credit net to zero readOnly: true totalDebit: type: number description: Sum of debit line amounts readOnly: true totalCredit: type: number description: Sum of credit line amounts readOnly: true balanceDifference: type: number description: Debit minus credit imbalance (zero when balanced) readOnly: true invoiceId: type: integer format: int64 description: Linked invoice ID readOnly: true paymentId: type: integer format: int64 description: Linked payment ID readOnly: true payrollId: type: integer format: int64 description: Linked payroll ID readOnly: true cashRegisterId: type: integer format: int64 description: Linked cash register ID readOnly: true lines: type: array description: Journal entry lines items: $ref: '#/components/schemas/JournalEntryLineDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true JournalEntryLineCostCenterDocument: type: object description: Cost-center allocation on a journal entry line. properties: id: type: integer format: int64 description: Allocation primary key readOnly: true costCenterId: type: integer format: int64 description: Cost center ID example: 10 costCenterName: type: string description: Cost center name readOnly: true subCostCenterId: type: integer format: int64 description: Sub cost center ID example: 11 subCostCenterName: type: string description: Sub cost center name readOnly: true amount: type: number description: Allocated amount example: 100 JournalEntryLineDocument: type: object description: Journal entry line (AsientoLinea). properties: id: type: integer format: int64 description: Line primary key readOnly: true lineNumber: type: integer format: int32 description: Sequential line number within the entry example: 1 viewLineNumber: type: integer format: int32 description: UI view line number (debit/credit pair grouping) example: 1 readOnly: true debit: type: boolean description: True for debit, false for credit example: true accountingAccountId: type: integer format: int64 description: Ledger account ID example: 100 accountingAccountName: type: string description: Ledger account name readOnly: true offsetAccountId: type: integer format: int64 description: Offset account ID example: 200 offsetAccountName: type: string description: Offset account name readOnly: true activityId: type: integer format: int64 description: Activity ID example: 1 activityName: type: string description: Activity name readOnly: true amount: type: number description: Line amount example: 150 concept: type: string description: Line concept / description extension: type: string description: Line extension text (legacy ampliacion) invoiceLineId: type: integer format: int64 description: Linked invoice line ID (legacy movimiento_id) readOnly: true costCenterAllocations: type: array description: Cost-center allocations for this line items: $ref: '#/components/schemas/JournalEntryLineCostCenterDocument' ItemTypeDocument: type: object description: 'Item type (TipoArticulo): per-company item classification and ledger mappings.' properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoArticulo is not versioned; always omitted) readOnly: true name: type: string description: Display name example: Mercanc├¡a description: type: string description: Description enabled: type: boolean description: Whether the item type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Owner company ID example: 1 companyName: type: string description: Owner company name readOnly: true itemCategory: type: string description: 'Item general category ÔÇö TipoGeneralArticulo enum (MERCADERIA | SERVICIO). Catalog: `GET /api/v2/catalogs/itemCategory`.' example: MERCADERIA associatedAccounts: type: array description: Ledger account mappings per company items: $ref: '#/components/schemas/AssociatedAccountsDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true InventoryCountAdjustmentRef: type: object description: Reference to a stock adjustment generated by finalising an inventory count. properties: id: type: integer format: int64 description: Primary key of the underlying stock adjustment. example: 1042 code: type: string description: 'Formatted code: {series}-{number padded to 6 digits}.' example: INV-ENT-000045 direction: type: string description: Direction of the adjustment. IN means stock was added to the warehouse; OUT means stock was removed. enum: - IN - OUT example: IN totalQuantity: type: number description: Sum of the absolute quantities of every line in the adjustment. example: 12 lineCount: type: integer format: int32 description: Number of lines in the adjustment. example: 3 href: type: string description: Path of the canonical v2 resource exposing this adjustment. example: /api/v2/inventory-entries/45 InventoryCountDocument: type: object description: Inventory count ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key. readOnly: true version: type: integer format: int32 description: Optimistic-lock version (OPTLOCK). readOnly: true status: type: string description: Lifecycle status. enum: - DRAFT - FINALIZED - DRAFT - FINALIZED readOnly: true code: type: string description: 'Formatted code: {series}-{number padded to 6 digits}.' readOnly: true series: type: string description: Numbering series. example: INV number: type: integer format: int64 description: Sequential number within the series. readOnly: true warehouseId: type: integer format: int64 description: Warehouse (Sucursal) being counted. example: 3 warehouseName: type: string description: Warehouse name. readOnly: true companyId: type: integer format: int64 description: Company ID derived from the warehouse. readOnly: true companyName: type: string description: Company name. readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset). Defaults to today on create if omitted. example: '2026-05-20T12:00:00+02:00' internalRef: type: string description: Internal reference (free text). notes: type: string description: Free-text notes describing the count. adjustmentReasonId: type: integer format: int64 description: Adjustment reason (TipoAjuste) ID applied to the auto-generated adjustments on finalisation. adjustmentReasonName: type: string description: Adjustment reason name. readOnly: true fullInventory: type: boolean description: Inventory mode flag. Inverted vs the legacy `contarSoloArticulosIntroducidos` flag. false = only listed products are considered; true = full warehouse close. skipReservedStock: type: boolean description: When true, calculated stock subtracts reservations. stockBalanced: type: boolean description: True once the count has been finalised and stock adjustments have been generated. Equivalent to `status == FINALIZED`. readOnly: true finalize: type: boolean description: When true, the count is created and finalised in a single transaction (requires CUADRAR_STOCK permission). writeOnly: true totalCountedUnits: type: number description: Sum of lines[].countedQuantity. readOnly: true totalCalculatedUnits: type: number description: Sum of lines[].calculatedQuantity. readOnly: true totalCountedCost: type: number description: Sum of lines[].countedQuantity * unitCost. readOnly: true totalCalculatedCost: type: number description: Sum of lines[].calculatedQuantity * unitCost. readOnly: true lines: type: array description: Counted lines with calculated baseline and differences. items: $ref: '#/components/schemas/InventoryCountLineDocument' stockAdjustments: type: array description: References to the stock adjustments generated by finalising. Empty / null while status == DRAFT. items: $ref: '#/components/schemas/InventoryCountAdjustmentRef' readOnly: true finalizedAt: type: string description: Timestamp of the finalize action. Null while DRAFT. readOnly: true finalizedBy: type: string description: User that finalised the count. Null while DRAFT. readOnly: true createdBy: type: string description: User that created the record. readOnly: true createdAt: type: string description: Creation timestamp. readOnly: true lastModifiedBy: type: string description: Last user that modified the record. readOnly: true lastModifiedAt: type: string description: Last modification timestamp. readOnly: true InventoryCountLineDocument: type: object description: Inventory count line ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key of the line. readOnly: true lineNumber: type: integer format: int32 description: 1-based ordinal of the line within the document. readOnly: true productId: type: integer format: int64 description: Product ID. Must be enabled and inventoriable. example: 120 productName: type: string description: Product display name. readOnly: true productSku: type: string description: Product reference / SKU. readOnly: true countedQuantity: type: number description: Counted quantity supplied by the client (absolute, not delta). Must be >= 0. example: 8 calculatedQuantity: type: number description: System stock at the moment differences were grouped. readOnly: true difference: type: number description: Counted minus calculated. Positive = entry on finalize, negative = exit. readOnly: true unitCost: type: number description: Unit cost considered for valuation purposes. readOnly: true GroupDocument: type: object description: Group (product catalog) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö not versioned) readOnly: true code: type: string description: Business code (unique) example: PREMIUM name: type: string description: Display name example: Premium description: type: string description: Description enabled: type: boolean description: Whether the group is enabled (defaults to true on create) example: true blockType: type: string description: System-level block marker (TipoBloqueo enum name). Null means no block. example: B_SYNC companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true EquivalenceSurchargeTypeDocument: type: object description: 'Equivalence surcharge type (TipoRE): per-company recargo de equivalencia rate and ledger mappings.' properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoRE is not versioned; always omitted) readOnly: true name: type: string description: Display name example: RE general 5,2 % description: type: string description: Description enabled: type: boolean description: Whether the surcharge type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Owner company ID example: 1 companyName: type: string description: Owner company name readOnly: true surchargeRate: type: number description: Equivalence surcharge percentage example: 5.2 associatedAccounts: type: array description: Ledger account mappings per company items: $ref: '#/components/schemas/AssociatedAccountsDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true EmployeePositionDocument: type: object description: Employee store position ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (employee positions are not versioned ÔÇö always null) readOnly: true code: type: integer format: int64 description: Business code (numeric, unique per company). Optional on create ÔÇö the WAR assigns the next sequential value via `getNextCodigo` when omitted. Pre-filled by `POST /employee-positions/new`. example: 5 name: type: string description: Display name example: Optometrista description: type: string description: Description enabled: type: boolean description: Whether the position is enabled (defaults to true on create) example: true blockType: type: string description: System-level block marker (TipoBloqueo enum name, e.g. B_SYNC). Null means no block. example: B_SYNC commissionsEnabled: type: boolean description: Whether employees in this position participate in commission schemes example: true companyId: type: integer format: int64 description: Owning company ID example: 1 companyName: type: string description: Owning company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true DocumentStatusDocument: type: object description: Custom document status (EstadoDocumento) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true code: type: string description: Business code example: PEND-01 name: type: string description: Display name example: Pending review description: type: string description: Description documentKind: type: string description: Document kind this status applies to (TipoDocumentoGlobal enum name) example: FAC_EMI statusType: type: string description: Base lifecycle bucket (TipoEstadoDocumento enum name, e.g. PENDIENTE) example: PENDIENTE colorHex: type: string description: Hex colour for status pill rendering example: '#FF5733' enabled: type: boolean description: Whether the status is active example: true communicationId: type: integer format: int64 description: System notification template ID (AvisoSistema) example: 12 communicationName: type: string description: System notification template display name (AvisoSistema) readOnly: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true lastActionSystem: type: string description: Last action origin system (BSystem enum name) example: GESMO readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true DepartmentDocument: type: object description: Employee department ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (departments are not versioned ÔÇö always null) readOnly: true code: type: integer format: int64 description: Business code (numeric, unique per company). Optional on create ÔÇö the WAR assigns the next sequential value via `getNextCodigo` when omitted. Pre-filled by `POST /departments/new`. example: 3 name: type: string description: Display name example: Optometr├¡a description: type: string description: Description enabled: type: boolean description: Whether the department is enabled (defaults to true on create) example: true blockType: type: string description: System-level block marker (TipoBloqueo enum name, e.g. B_SYNC). Null means no block. example: B_SYNC companyId: type: integer format: int64 description: Owning company ID example: 1 companyName: type: string description: Owning company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true ContactRef: type: object description: Contact person linked to a customer properties: id: type: integer format: int64 description: Contact ID name: type: string description: Contact name email: type: string description: Contact email phone: type: string description: Contact phone position: type: string description: Contact position/role CustomerAccountingAccountDocument: type: object description: Customer accounting account (con_cuentas_tercero) properties: id: type: integer format: int64 description: Accounting account line ID companyId: type: integer format: int64 description: Company ID this account belongs to companyName: type: string description: Company display name readOnly: true customerAccountId: type: integer format: int64 description: Customer account (CuentaContable) ID. Must reference an existing accounting account; codes are not auto-created. customerAccountCode: type: string description: Customer account code (cuenta principal) readOnly: true withholdingAccountId: type: integer format: int64 description: Withholding account (CuentaContable) ID. withholdingAccountCode: type: string description: Withholding account code readOnly: true creditorAccountId: type: integer format: int64 description: Creditor account (CuentaContable) ID. creditorAccountCode: type: string description: Creditor account code readOnly: true CustomerAddressDocument: type: object description: Customer address (ges_direccion) properties: id: type: integer format: int64 description: Address line ID code: type: string description: Address label / code (e.g. "Casa", "Oficina") country: type: string description: ISO 3166-1 country code example: ES countryName: type: string description: Country display name readOnly: true province: type: string description: Province / state municipality: type: string description: Municipality locality: type: string description: City / locality postalCode: type: string description: Postal / ZIP code streetType: type: string description: Street type (Calle, Avenida, ÔǪ) streetName: type: string description: Street name streetNumber: type: string description: Street number floor: type: string description: Floor door: type: string description: Door building: type: string description: Building / block staircase: type: string description: Staircase apartment: type: string description: Apartment / extension phone: type: string description: Contact phone for this address isBillingAddress: type: boolean description: Whether this is the default billing address isDefaultShippingAddress: type: boolean description: Whether this is the default shipping address CustomerDocument: type: object description: Customer ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Unique customer ID example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (ges_tercero.OPTLOCK / versionLocking) readOnly: true code: type: string description: Customer code (unique alphanumeric) example: C000042 readOnly: true series: type: string description: Series prefix example: C number: type: integer format: int64 description: Sequential number readOnly: true enabled: type: boolean description: Whether the record is enabled/active draft: type: boolean description: Draft record (not yet finalised). Mapped from Item.borrador. isCustomer: type: boolean description: Whether this counterparty acts as a customer (cliente). isSupplier: type: boolean description: Whether this counterparty acts as a supplier (proveedor). genericCounterparty: type: boolean description: Generic counterparty (not linked to a specific entity). counterpartyType: type: string description: 'Counterparty type (TipoTercero enum: PF, E, CC, PA, ...).' enum: - PF - E - CC - PA - G - DC - B - CE - CD - SC - PE - RC - TI - AS - MS - DE - SI - CX - CF - CJ - D - 'N' - EX example: PF checkDigit: type: integer format: int32 description: Check digit (LATAM tax-id verification digit). Optional. taxIdUnvalidated: type: boolean description: Tax ID was not yet validated against the official authority. firstName: type: string description: First name or business name example: John lastName: type: string description: Last name (null for companies) example: Doe businessName: type: string description: Full business name / raz├│n social example: ACME Corp SL taxId: type: string description: Tax identification number (NIF/NIE/CIF/RUT) example: B12345678 birthDate: type: string description: Date of birth (ISO 8601 date-only) example: '1980-05-20' gender: type: string description: 'Gender (TipoSexo enum: H=Male, M=Female, O=Other)' enum: - H - M - O example: H maritalStatus: type: string description: Marital status (EstadoCivil enum). enum: - SOLTERO - CASADO - DIVORCIADO - VIUDO - NODEFINIDO profession: type: string description: Profession / occupation blockType: type: string description: Block type (TipoBloqueo enum). Tracks sync/fiscal lifecycle blocks. leadType: type: string description: Lead type (TipoLead enum). enum: - LEAD - CLD - CL neighbour: type: boolean description: Marked as a neighbour (vecino). email: type: string description: Email address example: john@example.com phone: type: string description: Landline phone number example: '912345678' mobile: type: string description: Mobile phone number example: '612345678' phonePrefix: type: string description: Phone prefix / country code example: '+34' fax: type: string description: Fax number website: type: string description: Website URL contactPerson: type: string description: Contact person name contactSchedule: type: string description: Preferred contact schedule position: type: string description: Position / role at the company billingAddress: $ref: '#/components/schemas/AddressDto' description: Billing address shippingAddress: $ref: '#/components/schemas/AddressDto' description: Shipping / delivery address countryCode: type: string description: ISO 3166-1 country code example: ES billingAddressId: type: integer format: int64 description: FK to the default billing address (ges_direccion). shippingAddressId: type: integer format: int64 description: FK to the default shipping address (ges_direccion). companyId: type: integer format: int64 description: Company ID this customer belongs to warehouseId: type: integer format: int64 description: Warehouse / store ID warehouseName: type: string description: Warehouse / store name readOnly: true customerProfileId: type: integer format: int64 description: Customer profile ID associatedCompanyId: type: integer format: int64 description: Associated company (B2B parent / subsidiary link). lastWarehouseId: type: integer format: int64 description: Branch where the customer last placed an order/visit. readOnly: true lastEmployeeId: type: integer format: int64 description: Sales rep / employee who last attended the customer. readOnly: true bank: type: string description: Bank name checkingAccount: type: string description: Bank account number / checking account iban: type: string description: IBAN bic: type: string description: BIC/SWIFT code sepaFormat: type: string description: SEPA mandate format. enum: - CORE - B2B mandateSignDate: type: string description: Date the SEPA mandate was signed (ISO 8601 with business timezone offset). sepaReference: type: string description: SEPA mandate reference (free text identifying the signed mandate). invoiceBalance: type: number description: Outstanding invoice balance (computed by the legacy ledger). readOnly: true baseRateId: type: integer format: int64 description: Base rate (Tarifa) FK applied to this customer. baseRateQuota: type: number description: Credit quota for the base rate. example: 0 discountRateId: type: integer format: int64 description: Discount rate (Tarifa) FK applied to this customer. discountRateQuota: type: number description: Credit quota for the discount rate. example: 0 discountPercent: type: number description: Commercial discount percentage applied to this customer. paymentTermsId: type: integer format: int64 description: Payment terms (CondicionPago) FK. paymentMethodId: type: integer format: int64 description: Payment method (FormaDePago) FK. paymentDay1: type: integer format: int32 description: First preferred payment day of the month (1-31). example: 5 paymentDay2: type: integer format: int32 description: Second preferred payment day of the month (1-31). example: 20 vatIndicator: type: string description: 'VAT indicator (IndicadorIVA enum: N=Normal, R=WithSurcharge, E=Exempt).' enum: - 'N' - R - E example: 'N' assignedEmployeeId: type: integer format: int64 description: Sales rep / employee (Trabajador) assigned to this customer. excludeFromLoyaltyPoints: type: boolean description: Whether this customer is excluded from loyalty points accrual. disability: type: boolean description: Whether the customer has a recognised disability. allowMarketing: type: boolean description: Customer consents to marketing communications. allowSurveys: type: boolean description: Customer consents to surveys. sendReminders: type: boolean description: Customer wants to receive reminders. sendSystemNotifications: type: boolean description: Customer wants to receive system notifications. syncCrm: type: boolean description: Opt-in for CRM synchronisation (HighLevel / syncCRM). lopdConsent: type: boolean description: LOPD / privacy consent from the Cliente profile (avisos/publicidad). feediuId: type: string description: Feediu application id. Non-null means the customer has the app (legacy feediuEnviado). sourceSystem: type: string description: Origin system of the customer record (BSystem name, e.g. GESMO, CRM). observations: type: string description: General observations documentObservations: type: string description: Observations printed on documents agreementCounterpartyId: type: integer format: int64 description: FK to the agreement counterparty. primaryInsurerId: type: integer format: int64 description: Primary insurer (FK to a Tercero with insurer profile). secondaryInsurerId: type: integer format: int64 description: Secondary insurer (FK to a Tercero with insurer profile). tertiaryInsurerId: type: integer format: int64 description: Tertiary insurer (FK to a Tercero with insurer profile). primaryBeneficiaryNumber: type: string description: Beneficiary number with the primary insurer. secondaryBeneficiaryNumber: type: string description: Beneficiary number with the secondary insurer. tertiaryBeneficiaryNumber: type: string description: Beneficiary number with the tertiary insurer. insurerDocumentLimit: type: number description: Maximum document amount allowed for this insurer relationship. satTaxRegime: type: string description: SAT (M├®xico) tax regime code. example: '601' withholdingAgent: type: boolean description: Whether this counterparty acts as a withholding agent. withholdingPercent: type: number description: Withholding percentage applied when this counterparty is the withholding agent. receiverActivityCode: type: string description: Receiver economic activity code (LATAM e-invoicing). idDocumentType: type: string description: Identity document type (SII / fiscal classification). socialSecurity: type: string description: Social security number (national insurance ID). colombiaEpsCode: type: string description: Colombia EPS code (health insurance provider for RIPS). allowOrderWithoutDocumentControl: type: boolean description: Allows orders to be placed without strict document control checks. defaultLoyaltyWalletId: type: integer format: int64 description: Default loyalty wallet (CarteraPuntos) for this customer. directDebitMandateAttachmentId: type: integer format: int64 description: Attachment with the signed direct-debit mandate. customerPhotoAttachmentId: type: integer format: int64 description: Attachment with the customer's profile photo. noahId: type: string description: External hearing-aids (Noah) integration id. contacts: type: array description: Linked contacts (additional people at this customer) items: $ref: '#/components/schemas/ContactRef' readOnly: true addresses: type: array description: 'Secondary address book for this customer (ges_direccion). Read/write: full replacement of the collection.' items: $ref: '#/components/schemas/CustomerAddressDocument' relationships: type: array description: Customer relationships / linked people (ges_contacto). Read fully; write support is rolled out incrementally. items: $ref: '#/components/schemas/CustomerRelationshipDocument' loyaltyWallets: type: array description: Loyalty wallets the customer holds (CarteraPuntos). Surfaced to drive the relationship card-sharing UI. items: $ref: '#/components/schemas/LoyaltyWalletSummaryDocument' readOnly: true accountingAccounts: type: array description: Per-company accounting accounts (con_cuentas_tercero). Read fully; write support is rolled out incrementally. items: $ref: '#/components/schemas/CustomerAccountingAccountDocument' customFields: type: array description: User-defined custom fields. Same shape across every v2 entity. For Customer the catalog lives in cf_definition (ADR-003). items: $ref: '#/components/schemas/CustomFieldValueDocument' sapCode: type: string description: SAP partner code readOnly: true createdBy: type: string description: User who created this record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: User who last modified this record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true CustomerRelationshipDocument: type: object description: Customer relationship (ges_contacto) properties: id: type: integer format: int64 description: Relationship line ID linkedCustomerId: type: integer format: int64 description: Linked customer (Tercero) ID; null for a manual relationship. linkedCustomerDisplayName: type: string description: Linked customer display name readOnly: true linkedCustomerPhone: type: string description: Linked customer phone readOnly: true linkedCustomerLandline: type: string description: Linked customer landline readOnly: true linkedCustomerEmail: type: string description: Linked customer email readOnly: true linkedCustomerBirthDate: type: string description: Linked customer date of birth (ISO date) readOnly: true linkedCustomerAge: type: integer format: int32 description: Linked customer age readOnly: true relationshipTypeId: type: integer format: int64 description: Relationship type (TipoContactoAsociado) FK relationshipTypeName: type: string description: Relationship type display name readOnly: true linkApp: type: boolean description: Whether the relationship is linked to the customer app. firstName: type: string description: First name (manual relationship only) lastName: type: string description: Last name (manual relationship only) email: type: string description: Email (manual relationship only) contactSchedule: type: string description: Contact schedule (manual relationship only) contactPhone: type: string description: Contact phone (manual relationship only) sharedLoyaltyWallets: type: array description: Loyalty wallets of the holder shared with this relationship. items: $ref: '#/components/schemas/SharedLoyaltyWalletDocument' sharedLoyaltyWalletCount: type: integer format: int32 description: Count of shared loyalty wallets readOnly: true LoyaltyWalletSummaryDocument: type: object description: Loyalty wallet summary (CarteraPuntos) properties: id: type: integer format: int64 description: Loyalty wallet ID cardNumber: type: string description: Card number customerCode: type: string description: Customer code on the card cardLabel: type: string description: Display label pointsBalance: type: integer format: int32 description: Points balance monetaryValue: type: number description: Monetary value of the points pointsDisplay: type: string description: Formatted points display SharedLoyaltyWalletDocument: type: object description: Shared loyalty wallet entry properties: loyaltyWalletId: type: integer format: int64 description: Loyalty wallet (CarteraPuntos) ID cardNumber: type: string description: Card number readOnly: true customerCode: type: string description: Customer code on the card readOnly: true cardLabel: type: string description: Display label readOnly: true pointsBalance: type: integer format: int32 description: Points balance readOnly: true monetaryValue: type: number description: Monetary value of the points readOnly: true pointsDisplay: type: string description: Formatted points display readOnly: true shared: type: boolean description: Whether the wallet is shared with this relationship CustomerProfileDocument: type: object description: Customer profile (PerfilCliente) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (PerfilCliente is not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique, globally scoped in legacy schema) example: '10000034' name: type: string description: Display name example: Particular description: type: string description: Description example: Perfil para clientes particulares sin descuento especial enabled: type: boolean description: Whether the profile is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true basePriceListId: type: integer format: int64 description: Base price list (Tarifa TB/TBF) FK ÔÇö {@code PerfilCliente.tarifa} example: 10 basePriceListName: type: string description: Base price list name example: TARIFA ASOCIADO 1 readOnly: true discountPriceListId: type: integer format: int64 description: Discount price list (Tarifa DTO) FK ÔÇö {@code PerfilCliente.tarifaDto} example: 5 discountPriceListName: type: string description: Discount price list name example: Empleados readOnly: true paymentTermsId: type: integer format: int64 description: Payment terms (CondicionPago) FK ÔÇö {@code PerfilCliente.condicionesDePago} example: 3 paymentTermsName: type: string description: Payment terms name example: Contado readOnly: true allowsCredit: type: boolean description: Whether customers on this profile may use credit example: true isInsurer: type: boolean description: Whether this profile represents an insurer ({@code esAseguradora}) example: false isSupplier: type: boolean description: Whether this profile is for suppliers ({@code proveedor}) example: false isCorporateDivision: type: boolean description: Whether this profile is a corporate division example: false blockType: type: string description: Sync / fiscal block type ({@code TipoBloqueo} enum stored on the profile) example: B_SYNC notes: type: array description: Internal notes attached to this profile ({@code PerfilCliente.notas}) items: $ref: '#/components/schemas/NoteDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true CustomFieldDefinitionDocument: type: object description: Custom field definition (tenant catalog) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: 'Stable ID of the definition (cf_definition.id). It is the canonical wire identifier: RSQL paths use customFields. and the JSON storage key is the id stringified.' example: 7 readOnly: true version: type: integer format: int32 description: Optimistic lock version (echo back via If-Match). Null for EAV-backed featureTypes, which do not support optimistic locking yet (no ETag is emitted and If-Match is ignored). example: 0 readOnly: true featureType: type: string description: >- Owning feature, public v2 nomenclature. JSON-backed (cf_definition): customers, optometry-exams, audiology-exams, contactology-fittings, contact-lens-exams. EAV-backed bridge (ges_customfield, until ADR-003 Fase 3): product-models, product-variants, manufacturing-custom-fields. For EAV-backed featureTypes the id namespace is ges_customfield.id, so detail operations must repeat featureType as query parameter. example: customers apiName: type: string description: 'Machine name of the field (camelCase, unique per featureType). Display-oriented: it can be renamed without breaking stored values or saved filters (the stable key is `id`).' example: discountGroup dataType: type: string description: >- Data type. JSON-backed featureTypes: STRING, NUMBER, BOOLEAN, DATE, ENUM, TEXT. EAV-backed featureTypes (product-models, product-variants, manufacturing-custom-fields): STRING, NUMBER, ENUM, COLOR. example: ENUM label: type: string description: Human label shown by the SPA. example: Grupo de descuento required: type: boolean description: Whether a value is mandatory when writing the owning entity. example: false indexable: type: boolean description: Whether the field should be backed by an indexed generated column (Fase 2; the ALTER TABLE is a manual maintenance operation, this flag only records the intent). example: false options: type: array description: >- Seed of allowed option labels, accepted ONLY on creation of a dataType=ENUM definition (each label becomes a cf_definition_option row). Never returned on reads and rejected on updates: options are managed individually through the paginated sub-resource /api/v2/custom-field-definitions/{id}/options. example: - VIP - Standard items: type: string writeOnly: true optionCount: type: integer format: int64 description: Number of options of the definition (only for dataType=ENUM; 0 otherwise). Use the /options sub-resource to page through them. example: 3 readOnly: true displayOrder: type: integer format: int32 description: Relative display order inside its group. example: 10 displayGroup: type: string description: Visual group in the form. example: Comercial enabled: type: boolean description: Disabled definitions are hidden from schema discovery and rejected on writes, but their stored values are preserved. example: true companyId: type: integer format: int64 description: >- Owning company (ges_customfield.empresa_id). Only for EAV-backed featureTypes (product-models, product-variants, manufacturing-custom-fields); null for JSON-backed featureTypes, whose catalog is tenant-level. On creation it defaults to the authenticated user's current company when omitted. example: 1 createdBy: type: string description: User that created the definition readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601) readOnly: true lastModifiedBy: type: string description: Last user that modified the definition readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601) readOnly: true CustomFieldOptionDocument: type: object description: Allowed option of an ENUM custom field definition ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Stable ID of the option (cf_definition_option.id). example: 31 readOnly: true version: type: integer format: int32 description: Optimistic lock version (echo back via If-Match). Null for options of EAV-backed definitions, which do not support optimistic locking yet (no ETag is emitted and If-Match is ignored). example: 0 readOnly: true customFieldDefinitionId: type: integer format: int64 description: Owning custom field definition (cf_definition.id). example: 7 readOnly: true value: type: string description: Option label. It is both the display string and the value stored in the owning entity's customFields JSON. Unique within the definition. example: VIP displayOrder: type: integer format: int32 description: Relative display order inside the definition. example: 10 hex: type: string description: 'Hex color of the option. Only meaningful for dataType=COLOR definitions (EAV-backed featureTypes: product-models, product-variants, manufacturing-custom-fields); null otherwise.' example: '#FF0000' enabled: type: boolean description: Disabled options are hidden from schema discovery and rejected on entity writes, but previously stored values are preserved. example: true createdBy: type: string description: User that created the option readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601) readOnly: true lastModifiedBy: type: string description: Last user that modified the option readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601) readOnly: true CouponTypeDocument: type: object description: Coupon type (TipoPin) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoPin is not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique per company, used in ERP/sync) example: EMP10 name: type: string description: Display name example: Empleado 10% description: type: string description: Description enabled: type: boolean description: Whether the coupon type is enabled (defaults to true on create) example: true expirationDays: type: integer format: int32 description: Expiration in days from issue date (ignored when {@code expiresEndOfMonth=true}) expiresEndOfMonth: type: boolean description: Coupon expires at the end of the issue month instead of using {@code expirationDays} example: false userKind: type: string description: 'Beneficiary audience ({@code TipoPinClienteEmpleado} enum name: E=employee, C=customer)' enum: - E - C example: E nominative: type: boolean description: Customer coupons must be nominative (bound to a specific customer) example: false multipleUse: type: boolean description: Whether the same coupon code may be redeemed multiple times example: false requiresExternalReference: type: boolean description: Whether an external reference is required on redemption example: false discountKind: type: string description: 'Discount value semantics ({@code TipoValorPin} enum name: P=percentage, M=fixed amount)' enum: - P - M example: P discount: type: number description: Discount value ÔÇö percentage when {@code discountKind=P}, fixed amount when {@code discountKind=M} example: 10 allCategories: type: boolean description: When true, the coupon type applies to every product category example: true categoryIds: type: array description: Eligible category IDs when {@code allCategories=false}. Full replacement on write; empty list with {@code allCategories=false} clears the restriction. items: type: integer format: int64 companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true VerifactuConfigurationDocument: type: object description: Company-scoped VeriFactu configuration. properties: companyId: type: integer format: int64 description: Company ID. It must match the companyId path parameter. example: 3 antiFraudEnabled: type: boolean description: Whether anti-fraud invoice submission is enabled. example: true submissionMode: type: string description: Submission mode. enum: - VERIFACTU - NON_VERIFACTU example: VERIFACTU pattern: VERIFACTU|NON_VERIFACTU sendFullInvoicesAutomatically: type: boolean description: Automatically submit full invoices. example: true sendSimplifiedInvoicesAutomatically: type: boolean description: Automatically submit simplified invoices. example: false certificateId: type: string description: Opaque ID returned by the certificate upload operation. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificateName: type: string description: Original certificate filename. example: empresa.p12 readOnly: true certificateFingerprint: type: string description: SHA-256 fingerprint of the X.509 certificate. example: A1:B2:C3:D4 readOnly: true certificateExpiresAt: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). example: '2027-03-15T01:00:00+01:00' readOnly: true certificateUploadedAt: type: string description: Certificate upload timestamp (ISO 8601 with business offset). example: '2026-07-21T11:12:00+02:00' readOnly: true version: type: integer format: int32 description: Optimistic lock version. example: 4 readOnly: true createdBy: type: string description: User that created the configuration. readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset). readOnly: true lastModifiedBy: type: string description: Last user that modified the configuration. readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset). readOnly: true required: - antiFraudEnabled - companyId - sendFullInvoicesAutomatically - sendSimplifiedInvoicesAutomatically - submissionMode SatMexicoConfigurationDocument: type: object description: Company-scoped Mexico SAT (CFDI) configuration. properties: companyId: type: integer format: int64 description: Company ID. It must match the companyId path parameter. example: 3 active: type: boolean description: Whether Mexico SAT integration is enabled. example: true testMode: type: boolean description: Use the PAC test environment. example: true pacType: type: string description: PAC provider. enum: - CONTPAQ - FINKOK example: CONTPAQ pattern: CONTPAQ|FINKOK pacUser: type: string description: PAC user. example: sat-user pacPassword: type: string description: PAC password. Write-only; never returned by GET. writeOnly: true licenceId: type: string description: Contpaq licence ID. Write-only; never returned by GET. writeOnly: true syncInvoices: type: boolean description: Synchronize invoices. example: true syncIncomingPayments: type: boolean description: Synchronize incoming payments. example: true syncCreditNotes: type: boolean description: Synchronize credit notes. example: true syncPaymentCancel: type: boolean description: Synchronize payment cancellations. example: false hoursBlockedAfterRejectedCancellation: type: integer format: int32 description: Hours to block after a rejected cancellation. example: 24 hoursBeforeReinvoicing: type: integer format: int32 description: Hours to wait before re-invoicing. example: 0 globalBillingPerCompany: type: boolean description: Enable global billing per company. example: false globalPerTicket: type: boolean description: Emit one global invoice per ticket (1:1 lines). example: false globalDetailedPerLine: type: boolean description: Emit a detailed global invoice with one line per ticket line. example: false globalBillingPeriodicity: type: string description: Global billing periodicity (c_Periodicidad). 01=Daily, 02=Weekly, 03=Biweekly, 04=Monthly, 05=Bimonthly. example: '04' pattern: 0[1-5] globalProductId: type: integer format: int64 description: Generic product used for global billing. example: 456 globalBranchId: type: integer format: int64 description: Branch used for global billing. example: 12 globalCustomerId: type: integer format: int64 description: Customer used for global billing. example: 789 defaultPaymentMethodId: type: integer format: int64 description: Default payment method for global billing. example: 5 certificateId: type: string description: Opaque ID returned by the certificate upload operations. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificatePassword: type: string description: Private key password. Write-only; never returned by GET. writeOnly: true certificateName: type: string description: Original .cer filename. example: empresa.cer readOnly: true certificateKeyName: type: string description: Original .key filename. example: empresa.key readOnly: true certificateHolderName: type: string description: Certificate holder name (CN). readOnly: true certificateIssuerName: type: string description: Certificate issuer name (CN). readOnly: true certificateSerialNumber: type: string description: Certificate serial number. readOnly: true certificateValidFrom: type: string description: Certificate valid-from timestamp (ISO 8601 with business offset). readOnly: true certificateValidTo: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). readOnly: true certificateUploadedAt: type: string description: Certificate upload timestamp (ISO 8601 with business offset). readOnly: true version: type: integer format: int32 description: Optimistic lock version. example: 4 readOnly: true createdBy: type: string description: User that created the configuration. readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset). readOnly: true lastModifiedBy: type: string description: Last user that modified the configuration. readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset). readOnly: true required: - active - companyId - pacType DocumentControlConfigurationDocument: type: object description: >- Company-scoped document and payment control configuration. GET returns 404 until the first PUT creates the singleton. PUT is partial: null scalars/lists are ignored; use [] to clear categories. properties: id: type: integer format: int64 description: Configuration row ID. example: 12 readOnly: true companyId: type: integer format: int64 description: Company ID. It must match the companyId path parameter. example: 3 enableOrderPaymentControl: type: boolean description: Enable payment control on orders. example: true orderCategories: type: array description: Categories subject to order payment control. items: $ref: '#/components/schemas/EntityRef' orderMinimumChargedPercentage: type: number description: Minimum charged percentage required for order categories. Required in the stored configuration when enableOrderPaymentControl is true. example: 50 enableInvoicePaymentControl: type: boolean description: Enable payment control on invoices. example: true invoiceCategories: type: array description: Categories subject to invoice payment control. items: $ref: '#/components/schemas/EntityRef' invoiceMinimumChargedPercentage: type: number description: Minimum charged percentage required for invoice categories. Required in the stored configuration when enableInvoicePaymentControl is true. example: 100 enableTicketPaymentControl: type: boolean description: Enable payment control on simplified invoices / tickets. example: false ticketCategories: type: array description: Categories subject to ticket payment control. items: $ref: '#/components/schemas/EntityRef' ticketMinimumChargedPercentage: type: number description: Minimum charged percentage required for ticket categories. Required in the stored configuration when enableTicketPaymentControl is true. example: 100 enableSalesPaymentControl: type: boolean description: Enable payment control on sales documents. example: false salesMinimumChargedPercentage: type: number description: Minimum charged percentage required on sales. Required in the stored configuration when enableSalesPaymentControl is true. example: 100 forceFullPaymentOnInvoiceDelivery: type: boolean description: Force full payment when delivering invoices. example: false blockFullChargeOnOrders: type: boolean description: Reject full charge on orders. example: false orderExpirationDays: type: integer format: int32 description: Order expiration in days. example: 30 quoteExpirationDays: type: integer format: int32 description: Quote expiration in days. example: 15 blockOphthalmicLensLineSales: type: boolean description: Block ophthalmic lens sales outside the order form. example: true blockOrdersAfterSupplierRequest: type: boolean description: Block new orders once supplier requests have been placed. example: false headOfficeCategories: type: array description: Categories that must be requested from head office. items: $ref: '#/components/schemas/EntityRef' supplierFrameCategories: type: array description: Frame categories that must be requested from supplier. items: $ref: '#/components/schemas/EntityRef' allowNewOrdersOnInvoicesFromOrders: type: boolean description: Allow adding new orders on invoices generated from orders. example: false forceFullDeliveryOnInvoicesFromOrders: type: boolean description: Force full merchandise delivery on invoices from orders. example: false enableItemControlOnInvoicesFromOrders: type: boolean description: Enable item change control on invoices from orders. example: false changeableOrderInvoiceCategories: type: array description: Categories that can be changed on invoices from orders. items: $ref: '#/components/schemas/EntityRef' enableRepairArticleControl: type: boolean description: Restrict repair documents to selected categories only. example: false repairCategories: type: array description: Allowed categories on repair documents. items: $ref: '#/components/schemas/EntityRef' version: type: integer format: int32 description: Optimistic lock version. example: 4 readOnly: true createdBy: type: string description: User that created the configuration. readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset). readOnly: true lastModifiedBy: type: string description: Last user that modified the configuration. readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset). readOnly: true required: - companyId ChileSiiCafInfo: type: object description: Uploaded CAF metadata and folio range. properties: fileName: type: string description: Original CAF filename. example: caf_facturas.xml readOnly: true folioStart: type: integer format: int32 description: First authorized folio in the CAF. example: 1001 readOnly: true folioEnd: type: integer format: int32 description: Last authorized folio in the CAF. example: 1100 readOnly: true validUntil: type: string description: CAF authorization validity end date (ISO 8601 calendar day). example: '2026-07-20' readOnly: true ChileSiiConfigurationDocument: type: object description: Company-scoped Chile SII (Servicio de Impuestos Internos) configuration. properties: companyId: type: integer format: int64 description: Company ID. It must match the companyId path parameter. example: 3 active: type: boolean description: Whether Chile SII integration is enabled. example: true testMode: type: boolean description: Use the SII test environment. example: true autoSync: type: boolean description: Enable automatic synchronization. example: true syncReceipts: type: boolean description: Synchronize electronic receipts (boletas). example: true syncInvoices: type: boolean description: Synchronize electronic invoices. example: true syncExemptInvoices: type: boolean description: Synchronize exempt invoices. example: false syncDeliveryNotes: type: boolean description: Synchronize delivery notes (gu├¡as de despacho). example: true syncInternalDeliveryNotes: type: boolean description: Synchronize internal delivery notes. example: false syncCreditNotes: type: boolean description: Synchronize credit notes. example: true syncDebitNotes: type: boolean description: Synchronize debit notes. example: true syncPurchaseInvoices: type: boolean description: Synchronize electronic purchase invoices. example: false syncExportInvoices: type: boolean description: Synchronize export invoices. example: false syncExportCreditNotes: type: boolean description: Synchronize export credit notes. example: false syncExportDebitNotes: type: boolean description: Synchronize export debit notes. example: false syncExemptReceipts: type: boolean description: Synchronize exempt receipts. example: false syncMailCheck: type: boolean description: Poll the SII mailbox for incoming documents. example: false syncMailSend: type: boolean description: Send DTEs to customers by email. example: false companyTaxId: type: string description: Company tax ID (RUT) used by the SII connector. example: 76123456-7 senderRut: type: string description: RUT of the document sender. example: 76123456-7 recipientRut: type: string description: Deprecated envelope recipient RUT. example: 60803000-K verificationCode: type: string description: Deprecated SII verification code. resolutionDate: type: string description: SII resolution date (ISO 8601 with business offset). example: '2020-01-15T00:00:00-03:00' resolutionNumber: type: integer format: int32 description: SII resolution number. example: 80 defaultBranchId: type: integer format: int64 description: Default branch for inbound DTE processing. example: 12 genericProductId: type: integer format: int64 description: Generic product used for credit-note corrections. example: 456 certificateId: type: string description: Opaque ID returned by the certificate upload operation. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificatePassword: type: string description: PKCS#12 password. Write-only; never returned by GET. writeOnly: true certificateName: type: string description: Original certificate filename. example: empresa.p12 readOnly: true certificateFingerprint: type: string description: SHA-256 fingerprint of the X.509 certificate. example: A1:B2:C3:D4 readOnly: true certificateExpiresAt: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). example: '2027-03-15T01:00:00-03:00' readOnly: true certificateUploadedAt: type: string description: Certificate upload timestamp (ISO 8601 with business offset). example: '2026-07-22T11:12:00-03:00' readOnly: true certificateTaxIdWarning: type: string description: Non-blocking warning when the certificate tax ID differs from the company tax ID. readOnly: true mailHost: type: string description: IMAP host for inbound SII mail polling. example: imap.example.com mailPassword: type: string description: IMAP password. Write-only; never returned by GET. writeOnly: true mailPort: type: string description: IMAP port. example: '993' mailStoreProtocol: type: string description: IMAP store protocol. example: imaps mailUser: type: string description: IMAP user. example: sii@example.com receiptsCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true invoicesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true exemptInvoicesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true deliveryNotesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true creditNotesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true debitNotesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true exemptReceiptsCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true purchaseInvoicesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true exportInvoicesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true exportCreditNotesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true exportDebitNotesCaf: $ref: '#/components/schemas/ChileSiiCafInfo' readOnly: true version: type: integer format: int32 description: Optimistic lock version. example: 4 readOnly: true createdBy: type: string description: User that created the configuration. readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset). readOnly: true lastModifiedBy: type: string description: Last user that modified the configuration. readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset). readOnly: true required: - active - companyId CollectionDocument: type: object description: Collection ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (always null ÔÇö not versioned) readOnly: true code: type: string description: Business code (unique) example: OPT name: type: string description: Display name example: ├ôptica description: type: string description: Description enabled: type: boolean description: Whether the collection is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ClaimTypeDocument: type: object description: Claim type (ReclamoTipoReclamo) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true name: type: string description: Display name example: Defective lens description: type: string description: Description durationDays: type: integer format: int32 description: Default claim duration in days ({@code duracion}) example: 30 enabled: type: boolean description: Whether the claim type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true solutions: type: array description: >- Solution configurations for this claim type. null = no change on update; [] = clear all; non-empty list = full replacement. On create, send the initial rows here ÔÇö there is no separate solutions endpoint. items: $ref: '#/components/schemas/SolutionDocument' createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true ClaimCauseDocument: type: object description: Claim cause (ReclamoCausante) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true name: type: string description: Display name example: Supplier defect description: type: string description: Description enabled: type: boolean description: Whether the claim cause is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true CategoryDocument: type: object description: Category (product catalog hierarchy) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (categories are not versioned ÔÇö always null) readOnly: true code: type: string description: Business code example: OPT-LENTES name: type: string description: Display name example: Lentes Oft├ílmicas description: type: string description: Description enabled: type: boolean description: Whether the category is enabled (defaults to true on create) example: true blockType: type: string description: System-level block marker (TipoBloqueo enum name). Null means no block. example: B_SYNC blocked: type: boolean description: Whether the category is blocked example: false parentId: type: integer format: int64 description: Parent category ID. Null for root categories. example: 50 parentName: type: string description: Parent category name readOnly: true treeLeft: type: integer format: int32 description: Nested-set left bound (server-maintained) readOnly: true treeRight: type: integer format: int32 description: Nested-set right bound (server-maintained) readOnly: true equivalenceSurchargeApplies: type: boolean description: Equivalence surcharge applies for this category requiresPrescription: type: boolean description: Products in this category require an optical prescription requiresLot: type: boolean description: Products in this category are tracked by lot contactLenses: type: boolean description: Products in this category are contact lenses sunglasses: type: boolean description: Products in this category are sunglasses inventoriable: type: boolean description: Products in this category are tracked as inventory (defaults to true on create) allowsNegativeStock: type: boolean description: Allows negative stock when selling allowsReservationWithoutStock: type: boolean description: Allows creating reservations even when stock is 0 inHouseManufacturing: type: boolean description: Products are manufactured in-house viewType: type: string description: View type (determines form variant shown for products) example: DEFAULT productDescriptionPattern: type: string description: Pattern used to auto-build the product description example: ${CF:marca} ${CF:modelo} companyId: type: integer format: int64 description: Company ID (tenant) example: 1 companyName: type: string description: Company name readOnly: true articleTypeId: type: integer format: int64 description: Article type ID (accounting classification) articleTypeName: type: string description: Article type name readOnly: true vatTypeId: type: integer format: int64 description: VAT type ID example: 21 vatTypeName: type: string description: VAT type name readOnly: true expenseAccountId: type: integer format: int64 description: Expense accounting account ID expenseAccountName: type: string description: Expense accounting account name readOnly: true incomeAccountId: type: integer format: int64 description: Income accounting account ID incomeAccountName: type: string description: Income accounting account name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true CashCloseDocument: type: object description: Cash register close (Caja) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version. Caja has no OPTLOCK column, so this field is always null. readOnly: true code: type: string description: 'Formatted code: {series}/{number} (legacy {@code Caja.getCodigo()} uses slash; most v2 documents use hyphen ÔÇö see entity-mapping.md).' example: 1/42 readOnly: true series: type: string description: Numbering series (defaults to branch code on create) example: '1' readOnly: true number: type: integer format: int64 description: Sequential number within the series readOnly: true name: type: string description: Display name description: type: string description: Free-text description enabled: type: boolean description: Whether the record is enabled example: true draft: type: boolean description: Draft flag ÔÇö drafts are excluded from register-lock checks closeType: type: string description: Close kind ({@code TipoCaja.name()}). N=normal daily close, I=initial opening balance. enum: - 'N' - I example: 'N' open: type: boolean description: Whether the register period is still open for new payments example: false closeAt: type: string description: Closing timestamp (ISO 8601 with business timezone offset). Maps to legacy {@code Caja.fecha}. example: '2026-07-16T23:59:59+02:00' periodStartAt: type: string description: Start of the counted period (previous close end). Populated by calculate. readOnly: true periodEndAt: type: string description: End of the counted period (this close). Populated by calculate. readOnly: true incomeAmount: type: number description: Sum of incoming amounts across all payment methods readOnly: true outgoingAmount: type: number description: Sum of outgoing amounts across all payment methods readOnly: true calculatedAmount: type: number description: Net calculated amount across all payment methods readOnly: true countedAmount: type: number description: Physical count total across payment methods readOnly: true depositAmount: type: number description: Total cash withdrawals / deposits recorded on this close readOnly: true previousCashBalance: type: number description: Cash balance carried from the previous close readOnly: true cashBalance: type: number description: Cash balance for the counted period (cash payment kind only) readOnly: true changeKeptInRegister: type: number description: Change kept in the register ({@code cambioEnCaja}) vouchersIssuedAmount: type: number description: Vouchers issued in the period (negative cash movements) readOnly: true finalBalance: type: number description: Final cash balance after withdrawals ({@code previousCashBalance + cashBalance - depositAmount}) readOnly: true warehouseId: type: integer format: int64 description: Branch / store ID (required on create, immutable afterwards) example: 1 warehouseName: type: string description: Branch / store display name readOnly: true companyId: type: integer format: int64 description: Owning company ID readOnly: true companyName: type: string description: Owning company name readOnly: true withdrawalJournalEntryId: type: integer format: int64 description: Journal entry created for cash withdrawals readOnly: true lines: type: array description: >- Per-payment-method breakdown. Populated by calculate; on write clients may update {@code countedAmount} on existing lines (match by {@code id} or {@code paymentMethodId}). Other line amounts are ignored if sent and recomputed server-side. items: $ref: '#/components/schemas/CashCloseLineDocument' withdrawals: type: array description: >- Cash withdrawals linked to this close ({@code Cobro} with {@code transactionKind=MC} and {@code cashCloseId} pointing here). Writable on create/update when the branch tracks register withdrawals ({@code llevarcontrolretiradascaja}). The server derives {@code depositAmount} from the sum of withdrawal amounts. Null leaves the collection unchanged; an empty list clears it. Existing entries are matched by id and non-null fields are applied, preserving omitted optional values. items: $ref: '#/components/schemas/PaymentDocument' needsRecalculation: type: boolean description: 'Server-side hint: totals must be recalculated before save. Set by the client after changing {@code closeAt} or cleared by calculate.' writeOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true zreportNumber: type: integer format: int32 required: - closeAt - warehouseId CashCloseLineDocument: type: object description: Cash close line ÔÇö calculated and counted amounts per payment method. Only countedAmount is client-writable. properties: id: type: integer format: int64 description: Line primary key readOnly: true cashCloseId: type: integer format: int64 description: Parent cash close ID readOnly: true paymentMethodId: type: integer format: int64 description: Payment method ID. Writable to match lines on create/update when {@code id} is not yet assigned. paymentMethodName: type: string description: Payment method display name readOnly: true paymentKind: type: string description: Payment kind ({@code TipoFormaDePago}) enum: - E - T - V - C - O - R - I - P - D - B - G example: E readOnly: true incomeAmount: type: number description: Incoming amount for this payment method readOnly: true outgoingAmount: type: number description: Outgoing amount for this payment method readOnly: true calculatedAmount: type: number description: Net calculated amount for this payment method readOnly: true countedAmount: type: number description: Physically counted amount for this payment method. The only amount clients should send on write; the server aggregates line values into the parent {@code countedAmount}. CardTypeDocument: type: object description: Card type (TipoTarjeta) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoTarjeta is not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique per company, used in ERP sync) example: '1' name: type: string description: Display name example: Visa description: type: string description: Description creditAccount: type: string description: GL credit account code for card settlements (SAP CreditAcct / GLAccount) example: '57200001' enabled: type: boolean description: Whether the card type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true CancellationCauseDocument: type: object description: Cancellation cause (CausaAnulacion) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (not versioned ÔÇö always omitted) readOnly: true code: type: integer format: int64 description: Business code (unique, company-scoped). Optional on create ÔÇö the WAR assigns the next sequential value via `getNextCodigo` when omitted. Pre-filled by `POST /cancellation-causes/new`. example: 1001 name: type: string description: Display name example: Stock adjustment description: type: string description: Description abbreviation: type: string description: Short abbreviation shown in grids example: STK cancellationRecipientType: type: string description: 'Cancellation recipient type (TipoDestinatarioAnulacion enum: CLIENTE, FABRICA)' example: CLIENTE enabled: type: boolean description: Whether the cancellation cause is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true warehouseId: type: integer format: int64 description: Destination warehouse/branch ID (sucursal destino) example: 3 warehouseName: type: string description: Destination warehouse/branch name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true CampaignDocument: type: object description: Campaign (marketing) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version (campaigns are not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique) example: VERANO_2026 name: type: string description: Display name example: Rebajas Verano 2026 description: type: string description: Description enabled: type: boolean description: Whether the campaign is enabled (defaults to true on create) example: true startDate: type: string description: Campaign start timestamp (ISO 8601 with business offset) endDate: type: string description: Campaign end timestamp (ISO 8601 with business offset) companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true BrandDocument: type: object description: Brand (product catalog) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (brands are not versioned ÔÇö always null) readOnly: true code: type: string description: Business code (unique) example: NIKE name: type: string description: Display name example: Nike description: type: string description: Description enabled: type: boolean description: Whether the brand is enabled (defaults to true on create) example: true blockType: type: string description: System-level block marker (enum name from domain TipoBloqueo, e.g. B_SII, B_SAT, B_SYNC). Null means no block. example: B_SYNC companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true groupId: type: integer format: int64 description: Group ID (may be null) example: 7 groupName: type: string description: Group name (may be null) readOnly: true campaignId: type: integer format: int64 description: Campaign ID (may be null) example: 15 campaignName: type: string description: Campaign name (may be null) readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true AssociatedContactTypeDocument: type: object description: Associated contact type (TipoContactoAsociado) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (TipoContactoAsociado is not versioned ÔÇö always null) readOnly: true name: type: string description: Display name example: Spouse description: type: string description: Description linkApp: type: boolean description: Whether relationships of this type default to being linked with the customer app example: true enabled: type: boolean description: Whether the associated contact type is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Company ID example: 1 companyName: type: string description: Company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true AppointmentTypeDocument: type: object description: Appointment type / motive ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Examen visual description: type: string description: Description enabled: type: boolean description: Whether the type is enabled (defaults to true on create) color: type: string description: UI color for the calendar bubble enum: - BLUE - GREEN - RED - PURPLE - ORANGE - YELLOW - GREY - BLACK example: BLUE companyId: type: integer format: int64 description: Company ID companyName: type: string description: Company name readOnly: true serviceIds: type: array description: Linked appointment-service IDs. On write, the full list replaces the current one. items: type: integer format: int64 services: type: array description: Linked appointment services (id + name) ÔÇö denormalised for UI items: $ref: '#/components/schemas/EntityRef' readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true AppointmentServiceDocument: type: object description: Appointment service ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true version: type: integer format: int32 description: Optimistic lock version readOnly: true name: type: string description: Display name example: Lensometr├¡a description: type: string description: Description enabled: type: boolean description: Whether the service is enabled (defaults to true on create) companyId: type: integer format: int64 description: Company ID companyName: type: string description: Company name readOnly: true appointmentTypeIds: type: array description: Appointment types this service is available under. On write, the full list replaces the current one. items: type: integer format: int64 createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true ActivityDocument: type: object description: Accounting activity (Actividad) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 1 readOnly: true version: type: integer format: int32 description: Optimistic lock version (Actividad is not versioned ÔÇö always null) readOnly: true code: type: integer format: int64 description: Activity code (unique across the tenant) example: 1 name: type: string description: Display name example: Retail sales description: type: string description: Description enabled: type: boolean description: Whether the activity is enabled (defaults to true on create) example: true companyId: type: integer format: int64 description: Owning company ID example: 1 companyName: type: string description: Owning company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true AccountingAccountDocument: type: object description: Accounting account (chart of accounts entry) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key example: 42 readOnly: true version: type: integer format: int32 description: Optimistic lock version (accounting accounts are not versioned ÔÇö always omitted) readOnly: true account: type: string description: Full ledger account number (zero-padded). Recomputed on save from prefix and suffix when those are supplied. example: '43000001' prefix: type: string description: Account prefix (PGC root / grouping digits) example: '43' suffix: type: string description: Account suffix (sub-account digits within the prefix) example: '1' name: type: string description: Display name example: Clientes description: type: string description: Longer description enabled: type: boolean description: Whether the account is enabled (defaults to true on create) example: true rollupAccount: type: boolean description: Whether this row is a rollup (parent) account in the chart hierarchy example: false readOnly: true blockType: type: string description: System block marker (TipoBloqueo enum name, e.g. B_SYNC). Null means no block. example: B_SYNC companyId: type: integer format: int64 description: Owning company ID example: 1 companyName: type: string description: Owning company name readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp (ISO 8601 with business offset) readOnly: true JsonNode: type: object properties: array: type: boolean empty: type: boolean 'null': type: boolean float: type: boolean number: type: boolean string: type: boolean double: type: boolean object: type: boolean long: type: boolean pojo: type: boolean short: type: boolean int: type: boolean textual: type: boolean deprecated: true binary: type: boolean boolean: type: boolean valueNode: type: boolean bigDecimal: type: boolean container: type: boolean nodeType: type: string enum: - ARRAY - BINARY - BOOLEAN - MISSING - 'NULL' - NUMBER - OBJECT - POJO - STRING integralNumber: type: boolean missingNode: type: boolean bigInteger: type: boolean floatingPointNumber: type: boolean embeddedValue: type: boolean ViewTemplateCreateRequest: type: object description: Creation payload for a named view template. properties: featureType: type: string description: Registered featureType the template belongs to. example: brands name: type: string description: Template name, 1..60 chars after trim. Unique (case-insensitive) per (tenant, featureType, owner). example: Tienda visibility: type: string default: private description: Who can see the template. Creating with "everyone" requires the EDITAR_PLANTILLASGLOBALES permission. enum: - private - everyone columns: type: array description: Initial column layout (same shape and validation as saveViewLayout). PK, FK pair counterparts and ALWAYS_VISIBLE_COLUMN fields are added by the backend on the next GET. items: $ref: '#/components/schemas/ViewLayoutColumn' required: - columns - featureType - name ViewTemplateSummary: type: object description: Summary of a view template (system default or named saved template). properties: viewId: type: string description: 'Identifier usable in /api/v2/views/{viewId}: the slug for the system view (e.g. "brands-main") or the numeric plantilla id as string (e.g. "1042") for persisted templates.' example: '1042' plantillaId: type: - integer - 'null' format: int64 description: Numeric view_plantilla id. null for the system view. This is the value referenced by UserPreferencesDocument.viewTemplates[].viewId. example: 1042 featureType: type: string description: Canonical featureType of the listing. example: brands name: type: string description: Display name. The system view reports "Predeterminada". example: Tienda system: type: boolean description: true only for the {featureType}-main system view. visibility: type: string description: Who can see the template. enum: - private - everyone example: private ownerId: type: - integer - 'null' format: int64 description: userId of the creator. null for the system view. ownerName: type: - string - 'null' description: Display name of the owner (tooltip on shared templates). canEdit: type: boolean description: Whether the caller can PUT (columns) / PATCH (name, visibility) this template. canDelete: type: boolean description: Whether the caller can DELETE this template. updatedAt: type: - string - 'null' description: Last modification instant, ISO-8601 (UTC). example: '2026-07-01T10:15:30Z' FilterNodeDto: type: object description: Filter node inside a QueryDsl.filter (recursive). Either a leaf condition or a nested group. properties: logic: type: string description: Group combinator (`AND` / `OR`). Present only on group nodes. conditions: type: array description: Children (recursive). Present only on group nodes. items: $ref: '#/components/schemas/FilterNodeDto' field: type: string description: Field name. Present only on leaf nodes. operator: type: string description: Operator. Present only on leaf nodes. enum: - eq - neq - gt - gte - lt - lte - contains - notContains - startsWith - endsWith - in - between - blank - notBlank value: description: Operator value (or array for `in`). Present only on leaf nodes. valueTo: description: End value for `between`. Present only on leaf nodes when operator = between. leaf: type: boolean group: type: boolean GroupEntry: type: object description: Single grouping entry. Optional `aggFunctions` keyed by the field to aggregate. properties: field: type: string description: Field to group by. example: status aggFunctions: type: object additionalProperties: type: string description: Aggregations keyed by the field to aggregate (e.g. {"total":"sum"}). Pagination: type: object description: Pagination (offset / limit). 0-based offset. properties: offset: type: integer format: int32 description: 0-based row index to skip. example: 0 limit: type: integer format: int32 description: Max rows to return. Hard cap = 500. example: 100 QueryDsl: type: object description: Server-Side Row Model query (filter, sort, paginate, group). properties: pagination: $ref: '#/components/schemas/Pagination' description: Pagination (REQUIRED). Limit is capped at 500. sort: type: array description: Sort directives applied in order. items: $ref: '#/components/schemas/QuerySortEntry' filter: $ref: '#/components/schemas/FilterNodeDto' description: Filter tree (recursive). Use a `FilterGroup` (logic + conditions) at the root. search: type: string description: Full-text search. Applied case-insensitive over textual fields. example: ace grouping: type: array description: Server-Side row groups in order. items: $ref: '#/components/schemas/GroupEntry' groupKeys: type: array description: Drill-down keys for the parent groups already opened. items: type: string pivotColumns: type: array description: Pivot columns (reserved). items: type: string pivotMode: type: boolean description: Whether the request is in pivot mode (reserved). required: - pagination QuerySortEntry: type: object description: Single sort entry inside `QueryDsl.sort`. properties: field: type: string description: Column field to sort by. example: documentDate direction: type: string description: Sort direction. enum: - asc - desc example: desc ViewDataResponse: type: object description: Page of rows for a grid view. Fixed field name `rows`. properties: rows: type: array description: The rows. Each row carries `rowIdField` plus every visible field plus FK `_id` adjacents. items: type: object additionalProperties: {} rowCount: type: integer format: int32 description: Total filtered count (without pagination). Used by AG Grid to size scrollbars. example: 1342 SaveAsRoleRequest: type: object description: Persist the user's customized permission set as a new ERP role and assign it. properties: name: type: string maxLength: 80 minLength: 1 color: type: string description: Presentational color; echoed back, not persisted in the ERP. maxLength: 40 minLength: 0 description: type: string maxLength: 500 minLength: 0 required: - name AuthorizedIpRequest: type: object description: Authorize an IP or CIDR range. properties: ip: type: string example: 88.12.34.56 minLength: 1 description: type: string maxLength: 255 minLength: 0 required: - ip InviteUserRequest: type: object description: Invite a new back-office user. properties: firstName: type: string maxLength: 80 minLength: 0 lastName: type: string maxLength: 120 minLength: 0 email: type: string format: email minLength: 1 message: type: string maxLength: 500 minLength: 0 roleId: type: string description: Stable role id (OWNER/ADMIN/USER/SUPPORT or a custom role id). example: USER minLength: 1 branchAccess: type: array description: ERP branch ids granted on acceptance. items: type: string required: - email - roleId RemittanceDocument: type: object description: SEPA remittance (Remesa) ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key readOnly: true code: type: string description: 'Formatted code: {series}-{number}' example: REM1-42 readOnly: true series: type: string description: Numbering series (defaults to REM{companyId} on create) example: REM1 readOnly: true number: type: integer format: int64 description: Sequential number within the series readOnly: true name: type: string description: Display name (max 22 chars in legacy UI) example: Julio clientes maxLength: 22 minLength: 0 description: type: string description: Free-text description maxLength: 255 minLength: 0 enabled: type: boolean description: Whether the remittance is enabled. {@code Boolean} wrapper is intentional so merge-patch can omit the field without clearing it to false. example: true remittanceDate: type: string description: Requested SEPA collection date (calendar day, yyyy-MM-dd). Maps to {@code ReqdColltnDt} in the pain.008 file. example: '2026-07-14' receiptCount: type: integer format: int32 description: Number of receipt lines included in the batch readOnly: true total: type: number description: Sum of all line amounts readOnly: true companyId: type: integer format: int64 description: Owning company ID (required on create, immutable afterwards) example: 1 companyName: type: string description: Owning company name readOnly: true sepaXmlAttachmentId: type: integer format: int64 description: Generated SEPA XML attachment ID readOnly: true sepaXmlAttachment: $ref: '#/components/schemas/AttachmentRef' description: Generated SEPA XML attachment metadata readOnly: true sepaSignedXmlAttachmentId: type: integer format: int64 description: Bank-signed SEPA XML attachment ID readOnly: true sepaSignedXmlAttachment: $ref: '#/components/schemas/AttachmentRef' description: Bank-signed SEPA XML attachment metadata readOnly: true lines: type: array description: Persisted receipt lines items: $ref: '#/components/schemas/RemittanceLineDocument' readOnly: true candidateDateFrom: type: string description: Candidate filter start date when composing a new remittance (write-only hint, not persisted on the header) example: '2026-06-01' writeOnly: true candidateDateTo: type: string description: Candidate filter end date when composing a new remittance (write-only hint, not persisted on the header) example: '2026-06-30' writeOnly: true selectedCandidateKeys: type: array description: >- Candidate row keys selected on create (write-only). Each key matches {@link RemittanceCandidateDocument#rowKey} (e.g. F-12345 or V-67890). Uses the enum {@code .name()} token (F/V), not the translated {@code originType} label. items: type: string minItems: 1 writeOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true required: - candidateDateFrom - candidateDateTo - companyId - remittanceDate - selectedCandidateKeys RemittanceLineDocument: type: object description: SEPA remittance line ÔÇö receipt linked to an invoice or installment. All fields are read-only (lines are fixed at remittance creation). properties: id: type: integer format: int64 description: Line primary key readOnly: true lineNumber: type: integer format: int64 description: Sequential line number within the remittance readOnly: true remittanceId: type: integer format: int64 description: Parent remittance ID readOnly: true originType: type: string description: Source document kind ({@code RemesaOrigenTipo.name()}). F = open invoice without installments, V = unpaid installment due date. enum: - F - V example: V readOnly: true lineStatus: type: string description: Collection lifecycle status ({@code EstadoRemesaLinea.name()}). P=pending, G=generated, C=paid, A=accepted, R=rejected, D=returned, X=voided. enum: - P - G - C - A - R - D - X example: P readOnly: true sepaFormat: type: string description: SEPA direct-debit scheme for this receipt ({@code FormatoSepa.name()}) enum: - CORE - B2B example: CORE readOnly: true amount: type: number description: Amount to collect on this receipt example: 150 readOnly: true concept: type: string description: Debtor-facing concept shown in bank files and UI readOnly: true endToEndId: type: string description: SEPA End-to-End identification ({series}-{number}-{lineNumber}) readOnly: true counterpartyId: type: integer format: int64 description: Customer / debtor ID readOnly: true counterpartyName: type: string description: Customer / debtor display name readOnly: true counterpartyIban: type: string description: Customer IBAN used for the direct debit readOnly: true invoiceId: type: integer format: int64 description: Linked issued invoice ID when {@code originType=F} readOnly: true invoiceCode: type: string description: Formatted invoice code (series/number) readOnly: true installmentId: type: integer format: int64 description: Linked installment ID when {@code originType=V} readOnly: true createdBy: type: string description: User that created the record readOnly: true createdAt: type: string description: Creation timestamp (ISO 8601 with business timezone offset) readOnly: true lastModifiedBy: type: string description: Last user that modified the record readOnly: true lastModifiedAt: type: string description: Last modification timestamp readOnly: true RemittanceGeneratePaymentsRequest: type: object description: Remittance lines to register as incoming payments after bank collection. properties: lineIds: type: array description: Persisted remittance line IDs to mark as paid and generate cobros for example: - 101 - 102 items: type: integer format: int64 ProductImageUploadResponse: type: object description: Temporary product image uploaded to the legacy temp storage properties: temporaryImageId: type: string description: Temporary image identifier to send back in ProductDocument example: 1/producto-ajunto/123456789.jpg url: type: string description: URL that serves the temporary image for preview fileName: type: string description: Original file name without extension extension: type: string description: File extension example: jpg size: type: integer format: int64 description: File size in bytes example: 153204 ProductVariantSearchRequest: type: object description: 'Contextual product-variant (SKU) search for document forms. Read-only: nothing is persisted. Provide q (free text, * = wildcard) or barcode (exact match, scanner flow).' properties: branchId: type: integer format: int64 description: >- Branch (sucursal) of the document. Resolves the company search configuration (searchable custom fields / base price lists, ordering, supplier-reference search) and the per-branch stock context. example: 1 q: type: string description: Free-text needle matched against name, description, barcode and reference (and supplier reference when enabled). '*' acts as a wildcard. Exact barcode/reference matches sort first. example: RAY-BAN 2132 barcode: type: string description: Exact barcode (scanner flow). Takes precedence over q. example: '8412345678901' counterpartyId: type: integer format: int64 description: Customer/supplier (tercero) of the document. When the company has supplier-reference search enabled and the counterparty is a supplier, its per-product price references also match q. example: 1200 issued: type: boolean description: 'True for sales documents. Enables the sales-side restrictions: branch product lines, stock availability filter and lens blocking.' example: true categoryViewType: type: string description: Restrict to products whose category has this special view type (TipoProductoEspecial name, e.g. LEN_MONT). example: LEN_MONT excludeLenses: type: boolean description: Exclude lens/lens-option categories (legacy 'bloquearCristales'). Only applies when issued=true. example: false includeColumns: type: boolean description: Return the 'columns' metadata block (searchable custom fields, base price lists, display flags). Request it once per form session, not on every keystroke. example: false skip: type: integer format: int32 description: Rows to skip (pagination) example: 0 limit: type: integer format: int32 description: Max rows to return. Capped at 50; defaults to 20. example: 20 required: - branchId BasePrice: type: object description: Price of a variant in a searchable base price list properties: priceListId: type: integer format: int64 description: Base price list (tarifa) ID example: 10 priceListName: type: string description: Base price list name example: PVP General price: type: number description: Price in the list (semantics depend on finalPrice / taxIncluded) discountPct: type: number description: Discount percentage when the list entry is a discount instead of a final price finalPrice: type: boolean description: True when 'price' is a final price (vs. a discount) taxIncluded: type: boolean description: True when 'price' includes tax ColumnRef: type: object description: Id + name pair describing a dynamic panel column properties: id: type: integer format: int64 example: 42 name: type: string example: Calibre Columns: type: object description: Panel column metadata (company search configuration) properties: customFields: type: array description: Searchable custom field definitions, in display order items: $ref: '#/components/schemas/ColumnRef' basePriceLists: type: array description: Searchable base price lists, in display order items: $ref: '#/components/schemas/ColumnRef' showBrand: type: boolean description: Show the brand column example: true showCategory: type: boolean description: Show the category column example: true showStockMinusReserves: type: boolean description: Show stock minus reserves example: false searchBySupplierRef: type: boolean description: Supplier-reference search is active for the company example: false orderBy: type: string description: Default result ordering configured for the company enum: - REF - BARC - DES example: DES CustomFieldValue: type: object description: Searchable custom field value of a variant properties: fieldId: type: integer format: int64 description: Custom field definition ID example: 42 name: type: string description: Custom field name example: Calibre value: type: string description: Value for this variant example: '52' Item: type: object description: One product variant (SKU) row properties: id: type: integer format: int64 description: Variant (Producto/SKU) ID example: 12345 barCode: type: string description: Barcode / SKU example: '8412345678901' reference: type: string description: Internal reference example: RB2132-901 name: type: string description: Variant name description: type: string description: Variant description (default line description) categoryName: type: string description: Category name (display only) brandName: type: string description: Brand name (display only) salePriceNet: type: number description: Sheet sale price, tax excluded (informational) salePriceGross: type: number description: Sheet sale price, tax included (informational) inventoriable: type: boolean description: Whether the variant tracks stock stock: $ref: '#/components/schemas/StockInfo' description: Stock at the request branch (null when the variant has no stock row there) customFields: type: array description: Values of the company's searchable custom fields items: $ref: '#/components/schemas/CustomFieldValue' basePrices: type: array description: Prices in the company's searchable base price lists items: $ref: '#/components/schemas/BasePrice' ProductVariantSearchResponse: type: object description: Product-variant search results for the document-form panel. Prices are informational; lines are created via POST /pricing/preview. properties: items: type: array description: Matching variants, exact barcode/reference matches first items: $ref: '#/components/schemas/Item' skip: type: integer format: int32 description: Echo of the effective skip example: 0 limit: type: integer format: int32 description: Echo of the effective limit (after clamping) example: 20 hasMore: type: boolean description: True when more rows exist beyond skip+limit example: true columns: $ref: '#/components/schemas/Columns' description: Panel column metadata (only when includeColumns=true) StockInfo: type: object description: Stock at the request branch properties: quantity: type: number description: On-hand quantity example: 5 reserved: type: number description: Reserved quantity example: 2 available: type: number description: quantity - reserved example: 3 withoutStock: type: boolean description: True when the variant is inventoriable and available <= 0 (panel danger flag) example: false PricePreviewRequest: type: object description: Stateless request to resolve sales prices for a set of products against a document context. Nothing is persisted. properties: warehouseId: type: integer format: int64 description: Branch (sucursal) of the document example: 1 counterpartyId: type: integer format: int64 description: Customer (tercero) of the document; enables customer-specific prices example: 1200 basePriceListId: type: integer format: int64 description: Base price list (tarifa base) ID; null = product sheet price example: 10 discountPriceListId: type: integer format: int64 description: Discount price list (tarifa) ID; null = no tariff discounts example: 7 documentDate: type: string description: Document date (ISO 8601 date or datetime). Defaults to today. Drives tariff validity windows. example: '2026-07-14' currencyCode: type: string description: Document currency (ISO 4217). Defaults to the branch company's local currency. example: EUR exchangeRate: type: number description: Exchange rate of the document (LOCAL units per SYSTEM unit). Defaults to 1. Only used for the sheet-price fallback on companies configured to price from the system currency. example: 1 excludedTariffIds: type: array description: Tariff IDs the user opted out of (mirror of the per-line excludedTariffIds opt-out) items: type: integer format: int64 insurerIds: type: array description: Insurer (tercero aseguradora) IDs assigned to the document. For each one the response returns its document cap and, per item, the applicable condition (pct + line cap) by product category. items: type: integer format: int64 items: type: array description: Products to price items: $ref: '#/components/schemas/Item' minItems: 1 required: - items - warehouseId InsurerCondition: type: object description: Insurer condition applicable to the item properties: insurerId: type: integer format: int64 description: Insurer (tercero) ID example: 900 pct: type: number description: Coverage percentage over the line commercial net example: 50 capTaxIncluded: type: number description: Maximum contribution per LINE, tax included. Null = no line cap. InsurerInfo: type: object description: Insurer document context properties: insurerId: type: integer format: int64 description: Insurer (tercero) ID example: 900 insurerName: type: string description: Insurer display name documentCap: type: number description: Maximum insurer contribution per DOCUMENT (shared across lines, consumed in order). Null = no document cap. ItemResult: type: object description: Resolved pricing for one item properties: lineRef: type: string description: Client-side correlation ref echoed from the request example: tmp-1 productId: type: integer format: int64 description: Resolved product ID example: 12345 productName: type: string description: Product description (line description default) reference: type: string description: Product reference (line name default) barcode: type: string description: Product barcode vatTypeId: type: integer format: int64 description: VAT type of the product vatTypeName: type: string description: VAT type name vatPct: type: number description: VAT percentage applicable at the request branch example: 21 unitPrice: type: number description: Tax-excluded unit price (base price list or product sheet fallback) discountPct: type: number description: Commercial discount percentage resolved by the discount price list discountAmount: type: number description: Lineal (per-unit, tax-excluded) discount amount when the rule is a tax-excluded final price finalUnitPriceTaxIncluded: type: number description: Tax-INCLUDED final unit price when the rule fixes the customer price with tax (line total = value ├ù quantity) appliedPriceRule: $ref: '#/components/schemas/AppliedPriceRuleDocument' description: Pricing rule that produced the discount (tariff / combo) readOnly: true insurerConditions: type: array description: Applicable insurer conditions (one per requested insurer that covers the product's category) items: $ref: '#/components/schemas/InsurerCondition' errorCode: type: string description: Stable error code when this item could not be priced (the rest of the batch is still resolved) enum: - PRODUCT_NOT_FOUND - PRICE_NOT_IN_BASE_PRICE_LIST errorMessage: type: string description: Human-readable error detail PricePreviewResponse: type: object description: Resolved sales prices for a set of products (stateless preview). properties: warehouseId: type: integer format: int64 description: Echo of the request branch example: 1 basePriceListId: type: integer format: int64 description: Echo of the request base price list discountPriceListId: type: integer format: int64 description: Echo of the request discount price list currencyCode: type: string description: Currency the prices are expressed in (ISO 4217) example: EUR insurers: type: array description: Per-insurer document context (one entry per requested insurerId) items: $ref: '#/components/schemas/InsurerInfo' items: type: array description: Per-item resolved pricing, same order as the request items: $ref: '#/components/schemas/ItemResult' Filters: type: object description: Product filter block for bulk price operations. properties: categoryIds: type: array description: Restrict to these categories items: type: integer format: int64 brandIds: type: array description: Restrict to these brands items: type: integer format: int64 groupIds: type: array description: Restrict to these groups items: type: integer format: int64 campaignId: type: integer format: int64 description: Restrict to this campaign priceFrom: type: number description: Base price lower bound priceTo: type: number description: Base price upper bound description: type: string description: Product description contains reference: type: string description: Product reference contains barcode: type: string description: Product barcode contains assigned: type: boolean description: true = only products already having an entry in this price list; false = only products without one; null = all PriceListBulkEntriesRequest: type: object description: Bulk price assignment (POST /entries/bulk) or removal (POST /entries/bulk-delete) over the products matched by the filters. properties: action: type: string description: Batch action. Ignored on bulk-delete. enum: - DISCOUNT_PERCENT - FINAL_PRICE - FACTOR example: DISCOUNT_PERCENT value: type: number description: Value applied by the action (percentage, final price or factor). Ignored on bulk-delete and when comboConditionId is set (the condition carries its own value). vatIncluded: type: boolean description: The provided value includes VAT (FINAL_PRICE only) comboConditionId: type: integer format: int64 description: Attach the created entries to this combo condition (COM price lists) filters: $ref: '#/components/schemas/Filters' description: Product filters ÔÇö all optional, combined with AND PriceListBulkOperationResponse: type: object description: Result of a bulk price-list entry operation. properties: removed: type: integer format: int32 description: Rows deleted (bulk-delete) or conflicting rules removed (discount-rules) created: type: integer format: int32 description: Rules created (discount-rules). Null for bulk assignment, which is set-based. PriceListDiscountRuleRequest: type: object description: Discount rule creation by category/brand/group/campaign combination. properties: action: type: string description: Rule action enum: - DISCOUNT_PERCENT - FINAL_PRICE - FACTOR example: DISCOUNT_PERCENT value: type: number description: Value applied by the action (percentage, final price or factor) vatIncluded: type: boolean description: The provided value includes VAT comboConditionId: type: integer format: int64 description: Attach the rules to this combo condition (COM price lists) categoryIds: type: array description: Categories in scope (one rule per combination) items: type: integer format: int64 brandIds: type: array description: Brands in scope (one rule per combination) items: type: integer format: int64 groupIds: type: array description: Groups in scope (one rule per combination) items: type: integer format: int64 campaignId: type: integer format: int64 description: Campaign in scope LoyaltyWalletMemberChangeDocument: type: object description: Incremental add/remove of a customer on a loyalty wallet. properties: customerId: type: integer format: int64 description: Customer (Tercero) identifier. example: 501 customerOwner: type: boolean description: Whether the customer becomes the wallet owner. Only meaningful for ADD operations. example: false operation: type: string description: Operation to perform. enum: - ADD - REMOVE example: ADD LabelLineDocument: type: object description: 'A single label line: product, barcode, resolved prices and copies.' properties: productId: type: integer format: int64 description: Product (Producto) ID example: 12345 barcode: type: string description: Barcode printed on the label example: '6588648494687' productName: type: string description: Product name (denormalised) example: A RAYBAN 0RX3447 readOnly: true description: type: string description: Description printed on the label (editable) example: A RAYBAN 0RX3447 Vista priceOriginal: type: number description: Original price before discount (struck through when discounted); resolved by the pricing engine example: 145 priceFinal: type: number description: Final price (PVP) printed on the label (editable) example: 145 discounted: type: boolean description: Whether a discount applied (priceFinal < priceOriginal) example: false readOnly: true freeFooter: type: string description: Optional free footer text (pie de etiqueta); only used by formats with supportsFreeField=true example: Garantia 2 anios copies: type: integer format: int32 description: Number of copies of this label to print example: 100 LabelRenderRequest: type: object description: Request to render a label batch into a print job (PDF or ZPL). properties: formatCode: type: string description: Selected label format code example: punched-3x8 minLength: 1 printPaper: type: string description: Paper format for the print sheet (TipoPapelImpresora name) enum: - A4 - A5 - T80 example: A4 blankSpaces: type: integer format: int32 description: Number of blank label slots to leave before the first label (espacios en blanco / huecos) example: 2 lines: type: array description: Final label lines to print (barcode, description, prices, copies) items: $ref: '#/components/schemas/LabelLineDocument' required: - formatCode - lines LabelPrintJobDocument: type: object description: A rendered label print job (PDF or ZPL) as a base64 payload. properties: medium: type: string description: Output medium enum: - PDF - ZEBRA_ZPL example: PDF readOnly: true mimeType: type: string description: MIME type of the decoded content example: application/pdf readOnly: true filename: type: string description: Suggested download filename example: etiquetas.pdf readOnly: true contentBase64: type: string description: Base64-encoded content (the PDF bytes, or the ZPL text as bytes) readOnly: true pageCount: type: integer format: int32 description: Number of pages/sheets (PDF only; null for ZPL) example: 9 readOnly: true LabelPreviewRequest: type: object description: Request to resolve label prices for a set of products. properties: formatCode: type: string description: Selected label format code example: punched-3x8 minLength: 1 basePriceListId: type: integer format: int64 description: Base price list (tarifa base) ID; null = product sheet price (precio de ficha) example: 10 warehouseId: type: integer format: int64 description: Branch (sucursal) whose local discounts apply example: 1 items: type: array description: Products to resolve, with an optional per-item copy count items: $ref: '#/components/schemas/Item' required: - formatCode - items - warehouseId LabelBatchDocument: type: object description: A resolved label batch with priced lines, ready to edit and render. properties: formatCode: type: string description: Selected label format code example: punched-3x8 basePriceListId: type: integer format: int64 description: Base price list (tarifa base) used to resolve prices; null means the product's own sheet price (precio de ficha) example: 10 warehouseId: type: integer format: int64 description: Branch (sucursal) whose local discounts are applied example: 1 lines: type: array description: Resolved label lines items: $ref: '#/components/schemas/LabelLineDocument' defaultCopies: type: integer format: int32 description: Default number of copies applied to every line example: 1 InventoryAdjustmentLineDocument: type: object description: Manual inventory adjustment line ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key of the line. readOnly: true lineNumber: type: integer format: int32 description: 1-based ordinal of the line within the document. readOnly: true productId: type: integer format: int64 description: Product ID. Must be enabled and inventoriable. example: 120 productName: type: string description: Product display name. readOnly: true productSku: type: string description: Product reference / SKU. readOnly: true quantity: type: number description: Quantity moved by this line. Always positive; the direction (entry or exit) is given by the parent endpoint. example: 5 unitCost: type: number description: Unit cost applied to the line. Defaults to the product's purchase price when omitted. example: 12.5 totalCost: type: number description: Total cost = quantity * unitCost. readOnly: true notes: type: string description: Free-text annotation for this line. InventoryExitDocument: type: object description: Manual inventory exit ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key. readOnly: true version: type: integer format: int32 description: Optimistic-lock version of the underlying Traspaso. readOnly: true code: type: string description: 'Formatted code: {series}-{number padded to 6 digits}.' readOnly: true series: type: string description: Numbering series. example: SAL-MAN number: type: integer format: int64 description: Sequential number within the series. readOnly: true warehouseId: type: integer format: int64 description: Source warehouse (Sucursal) ID. example: 3 warehouseName: type: string description: Source warehouse name. readOnly: true companyId: type: integer format: int64 description: Company ID derived from the warehouse. readOnly: true companyName: type: string description: Company name. readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset). Defaults to today on create if omitted. internalRef: type: string description: Internal reference (free text). externalRef: type: string description: External reference (free text). notes: type: string description: Free-text notes describing the reason for the adjustment. trackingCode: type: string description: Free-text tracking code (codSeguimiento). adjustmentReasonId: type: integer format: int64 description: Adjustment reason (TipoAjuste) ID. adjustmentReasonName: type: string description: Adjustment reason name. readOnly: true totalQuantity: type: number description: Sum of all lines' quantity (always positive). readOnly: true totalCost: type: number description: Sum of all lines' totalCost. readOnly: true lines: type: array description: Lines being removed from the warehouse stock. items: $ref: '#/components/schemas/InventoryAdjustmentLineDocument' createdBy: type: string description: User that created the record. readOnly: true createdAt: type: string description: Creation timestamp. readOnly: true lastModifiedBy: type: string description: Last user that modified the record. readOnly: true lastModifiedAt: type: string description: Last modification timestamp. readOnly: true InventoryEntryDocument: type: object description: Manual inventory entry ÔÇö unified read/write document. properties: id: type: integer format: int64 description: Primary key. readOnly: true version: type: integer format: int32 description: Optimistic-lock version of the underlying Traspaso. readOnly: true code: type: string description: 'Formatted code: {series}-{number padded to 6 digits}.' readOnly: true series: type: string description: Numbering series. example: ENT-MAN number: type: integer format: int64 description: Sequential number within the series. readOnly: true warehouseId: type: integer format: int64 description: Destination warehouse (Sucursal) ID. example: 3 warehouseName: type: string description: Destination warehouse name. readOnly: true companyId: type: integer format: int64 description: Company ID derived from the warehouse. readOnly: true companyName: type: string description: Company name. readOnly: true documentDate: type: string description: Document date (ISO 8601 with business timezone offset). Defaults to today on create if omitted. internalRef: type: string description: Internal reference (free text). externalRef: type: string description: External reference (free text). notes: type: string description: Free-text notes describing the reason for the adjustment. trackingCode: type: string description: Free-text tracking code (codSeguimiento). adjustmentReasonId: type: integer format: int64 description: Adjustment reason (TipoAjuste) ID. adjustmentReasonName: type: string description: Adjustment reason name. readOnly: true totalQuantity: type: number description: Sum of all lines' quantity (always positive). readOnly: true totalCost: type: number description: Sum of all lines' totalCost. readOnly: true lines: type: array description: Lines being added to the warehouse stock. items: $ref: '#/components/schemas/InventoryAdjustmentLineDocument' createdBy: type: string description: User that created the record. readOnly: true createdAt: type: string description: Creation timestamp. readOnly: true lastModifiedBy: type: string description: Last user that modified the record. readOnly: true lastModifiedAt: type: string description: Last modification timestamp. readOnly: true VerifactuCertificateUploadResponse: type: object description: Staged Verifactu certificate metadata. Never contains binary data or passwords. properties: certificateId: type: string description: Opaque certificate ID to use in VerifactuConfigurationDocument. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificateName: type: string description: Original filename. example: empresa.p12 certificateFingerprint: type: string description: SHA-256 fingerprint of the X.509 certificate. example: A1:B2:C3:D4 certificateExpiresAt: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). example: '2027-03-15T01:00:00+01:00' certificateUploadedAt: type: string description: Upload timestamp (ISO 8601 with business offset). example: '2026-07-21T11:12:00+02:00' SatMexicoCertificateUploadResponse: type: object description: Staged Mexico SAT certificate metadata. Never contains binary data or passwords. properties: certificateId: type: string description: Opaque certificate ID to use in SatMexicoConfigurationDocument. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificateName: type: string description: Original .cer filename. example: empresa.cer certificateHolderName: type: string description: Certificate holder name (CN). certificateIssuerName: type: string description: Certificate issuer name (CN). certificateSerialNumber: type: string description: Certificate serial number. certificateValidFrom: type: string description: Certificate valid-from timestamp (ISO 8601 with business offset). certificateValidTo: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). certificateUploadedAt: type: string description: Upload timestamp (ISO 8601 with business offset). SatMexicoCertificateKeyUploadResponse: type: object description: Staged Mexico SAT private key metadata. Never contains binary data. properties: certificateId: type: string description: Opaque certificate ID bound to the staged .cer and .key pair. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificateKeyName: type: string description: Original .key filename. example: empresa.key ChileSiiCertificateUploadResponse: type: object description: Staged Chile SII certificate metadata. Never contains binary data or passwords. properties: certificateId: type: string description: Opaque certificate ID to use in ChileSiiConfigurationDocument. example: cert_01f13f9b-17b6-4baf-bf42-87310dbdf25e certificateName: type: string description: Original filename. example: empresa.p12 certificateFingerprint: type: string description: SHA-256 fingerprint of the X.509 certificate. example: A1:B2:C3:D4 certificateExpiresAt: type: string description: Certificate expiry timestamp (ISO 8601 with business offset). example: '2027-03-15T01:00:00-03:00' certificateUploadedAt: type: string description: Upload timestamp (ISO 8601 with business offset). example: '2026-07-22T11:12:00-03:00' certificateTaxIdWarning: type: string description: Non-blocking warning when the certificate tax ID differs from the company tax ID. ChileSiiCafUploadResponse: type: object description: Uploaded CAF metadata. Never contains binary data. properties: documentType: type: string description: Document type the CAF was validated for. enum: - RECEIPTS - INVOICES - EXEMPT_INVOICES - DELIVERY_NOTES - CREDIT_NOTES - DEBIT_NOTES - EXEMPT_RECEIPTS - PURCHASE_INVOICES - EXPORT_INVOICES - EXPORT_CREDIT_NOTES - EXPORT_DEBIT_NOTES example: INVOICES fileName: type: string description: Original CAF filename. example: caf_facturas.xml folioStart: type: integer format: int32 description: First authorized folio in the CAF. example: 1001 folioEnd: type: integer format: int32 description: Last authorized folio in the CAF. example: 1100 validUntil: type: string description: CAF authorization validity end date (ISO 8601 calendar day). example: '2026-07-20' version: type: integer format: int32 description: Optimistic lock version after persisting the CAF. example: 5 BulkPatchRequest: type: object description: 'Bulk patch request: applies `patch` to every id in `ids` (all-or-nothing).' properties: ids: type: array description: List of entity IDs to update. Must not be empty. If any id is missing or outside the authenticated user's company scope, the whole operation is rolled back with HTTP 400. example: - 1 - 2 - 3 items: type: integer format: int64 patch: type: object additionalProperties: {} description: JSON object with the fields to apply to every id. Each resource publishes its own whitelist; unknown or non-editable fields are rejected with HTTP 400. example: enabled: false blockType: B_SYNC BulkPatchResponse: type: object description: 'Bulk patch response: number of entities updated.' properties: updated: type: integer format: int32 description: Number of entities updated example: 3 ViewTemplatePatchRequest: type: object description: Merge-patch of a named view template (name and/or visibility). properties: name: type: - string - 'null' description: New name (same rules as in create). Omit to keep the current one. example: Tienda visibility: type: - string - 'null' description: New visibility. Switching to "everyone" requires the EDITAR_PLANTILLASGLOBALES permission. Omit to keep the current one. enum: - private - everyone TemplateUpdateRequest: type: object description: Change the list template applied to a feature for this user. properties: listTemplate: type: string description: Named template id (numeric) or 'default' to clear the selection. example: '239' minLength: 1 pattern: default|\d{1,18} required: - listTemplate ModuleUpdateRequest: type: object description: Enable/disable a module for the user (customized mode only). properties: enabled: type: boolean required: - enabled MatrixUpdateRequest: type: object description: Toggle one matrix cell (customized mode only). properties: actionId: type: string description: 'Column id: ALL or a TipoPermiso enum name.' example: CREAR minLength: 1 pattern: '[A-Z_]{1,40}' enabled: type: boolean required: - actionId - enabled CustomizationRequest: type: object description: Switch between role-inherited and customized permissions. properties: customized: type: boolean description: true = copy the role's permissions into a private editable set; false = (re)assign the ERP role and drop the private set. roleId: type: string description: ERP role id (core_role.id). Source of the copy when customizing; the role to assign when customized=false. example: '3' minLength: 1 pattern: \d{1,18} required: - customized - roleId IpRestrictionsPatchRequest: type: object description: Enable/disable the per-user IP whitelist. properties: enabled: type: boolean required: - enabled DevicePatchRequest: type: object description: Partial device update. properties: trusted: type: boolean active: type: boolean PageResponse: type: object description: Paginated response wrapper properties: data: type: array description: Items in the current page items: {} totalCount: type: integer format: int64 description: Total number of matching records across all pages example: 142 skip: type: integer format: int32 description: Number of records skipped to reach this page example: 0 limit: type: integer format: int32 description: Maximum records requested per page example: 50 hasMore: type: boolean description: Whether additional records exist after this page example: true ActionDef: type: object description: 'Backend-provided grid action: edit, delete, approve, etc.' properties: id: type: string description: Stable identifier. example: delete label: type: string description: Translated label. example: Eliminar icon: type: string description: Icon registry key. example: trash scope: description: Where the action is rendered. Either a single scope or an array. example: row origin: type: string description: Always `backend` from this API. example: backend permission: type: string description: Permission name (informative; backend already filters). example: BORRAR_MARCAS selectionMode: type: string description: Selection cardinality required for the action to be enabled. enum: - single - multi - any - none example: single destructive: type: boolean description: If true, the SPA shows a confirmation dialog and styles the action as destructive. disabled: type: boolean description: If true, the SPA renders the action greyed-out instead of hiding it. showWhen: type: string description: Visibility hint for footer-scoped actions. enum: - create - edit - view - always aiDescription: type: string description: Description used by the AI agent to invoke the action programmatically. execution: $ref: '#/components/schemas/ActionExecution' description: How the SPA should execute the action. ActionExecution: type: object description: 'How the SPA should execute this action: endpoint call or open dialog.' properties: type: type: string description: Execution kind. enum: - endpoint - dialog example: endpoint method: type: string description: HTTP method when `type = endpoint`. Defaults to GET. enum: - GET - POST - PUT - PATCH - DELETE example: DELETE url: type: string description: Target URL when `type = endpoint`. Supports placeholders like `:id`. example: /api/v2/brands/:id body: type: object additionalProperties: {} description: Optional fixed body. The SPA forwards it as JSON request payload (and may merge in the row/selection context). CatalogDefinition: type: object description: Catalog key, source and contextual parameter contract. properties: key: type: string example: priceList source: type: string enum: - STATIC - DYNAMIC companyRequired: type: boolean description: Whether companyId is mandatory. parameters: type: array items: $ref: '#/components/schemas/CatalogParameterDefinition' required: - companyRequired - key - parameters - source CatalogParameterDefinition: type: object description: Contextual query parameter accepted by a catalog. properties: name: type: string example: forSales type: type: string enum: - STRING - BOOLEAN - LONG required: type: boolean required: - name - required - type ColumnDefinition: type: object description: 'Column descriptor: name, type, filtering / sorting / grouping options, optional renderer.' properties: field: type: string description: Field key in each row of the data response. Must be stable and unique. example: name headerName: type: string description: Visible label, already translated according to `Accept-Language`. example: Nombre type: type: string description: Logical column type. Drives the default filter and renderer. enum: - text - number - date - dateTime - boolean - currency - percentage - enum example: text hide: type: boolean description: If true, column exists but is hidden by default. sortable: type: boolean description: Whether the user may sort by this column. Default true. editable: type: boolean description: Whether the cell is editable inline. Edits target the entity CRUD endpoint. bulkEditable: type: boolean description: Whether this column is included in the `bulkUpdate` action (multi-row form). Driven by FieldCapability.BULK_EDITABLE. width: type: integer format: int32 description: Initial width in pixels. AG Grid auto-fits when omitted. filter: type: string description: Optional explicit AG Grid filter override. enum: - agTextColumnFilter - agNumberColumnFilter - agDateColumnFilter - agSetColumnFilter filterParams: $ref: '#/components/schemas/FilterParams' description: Filter customisation (values, catalog, buttons, etc.). enableRowGroup: type: boolean description: Whether the user can group by this column (requires `capabilities.canGroup`). aggFunc: type: string description: Default aggregation function for grouping. enum: - sum - avg - min - max - count cellRenderer: type: string description: Semantic key of a frontend renderer (e.g. `StatusSwitch`, `RelationCell`). cellRendererParams: type: object additionalProperties: {} description: Free-form params forwarded to the cell renderer. featureType: type: string description: If the column is a foreign key, the canonical featureType of the referenced entity. example: groups navigable: description: Activates a clickable badge to the referenced entity. `true` reads `row[field+"_id"]`; a string overrides the id field. FilterParams: type: object description: AG Grid filter customisation parameters. properties: values: type: array description: Static values for a Set Filter. Mutually exclusive with `catalog`. items: {} catalog: type: string description: Dynamic catalog key. SPA resolves it via `GET /api/v2/catalogs/{catalog}`. catalogParams: $ref: '#/components/schemas/CatalogDefinition' description: >- Contract of `catalog`: whether it requires `companyId` and which contextual parameters it accepts. Present only when the catalog needs context beyond `q`/`limit`, so the SPA knows what to send (or that it cannot resolve the Set Filter without a company scope). suppressSorting: type: boolean description: Whether the filter UI hides the sort affordance. defaultToNothingSelected: type: boolean description: Whether the Set Filter starts with no items selected. buttons: type: array description: Buttons rendered in the filter popup. enum: - apply - clear - reset - cancel items: type: string ViewCapabilities: type: object description: View-level capabilities. Controls which AG Grid features the SPA enables. properties: canFilter: type: boolean description: Whether column filters are allowed. Default true. canSort: type: boolean description: Whether column sorting is allowed. Default true. canGroup: type: boolean description: Whether row grouping is allowed (enables `enableRowGroup` per column). Default false. canPivot: type: boolean description: Whether pivot mode is allowed. Default false. canExport: type: boolean description: Whether the toolbar shows an export button. Default false. ViewDefinition: type: object description: 'Metadata for an SPA grid view: columns, default sort, capabilities, actions and the user''s persisted UI state.' properties: viewId: type: string description: Same slug as the path, useful for clients that cache responses. example: brands-main featureType: type: string description: Canonical entity key in kebab-plural English (e.g. "brands", "products"). Lets the SPA resolve the local feature. example: brands rowIdField: type: string description: Row attribute used by AG Grid as `getRowId`. REQUIRED, stable, unique per row. example: id defaultSort: type: array description: Default sort applied when the user does not supply one. items: $ref: '#/components/schemas/SortModel' columns: type: array description: Visual order of columns. The order of this array is the base column order. items: $ref: '#/components/schemas/ColumnDefinition' actions: type: array description: Backend-provided actions (origin = backend). Frontend may inject additional fn/assign/merge actions. items: $ref: '#/components/schemas/ActionDef' userState: $ref: '#/components/schemas/UserGridState' description: Persisted UI state for the authenticated user. Absent if the user has none. capabilities: $ref: '#/components/schemas/ViewCapabilities' description: Capabilities enabled for this view (filtering, sorting, grouping, pivot, export). AvailableFieldDescriptor: type: object description: Field offered by the column picker for a view. properties: apiName: type: string description: Stable apiName (native FieldDef or customFields.). example: name label: type: string description: Default label, ready for display (Spanish). example: Nombre group: type: string description: Logical group hint. Useful to render sections in the picker. example: Identificaci├│n type: type: string description: Wire-level type (text, number, date, dateTime, boolean, currency, percentage, enum). example: text category: type: string description: 'FieldDef category: BUSINESS / CALCULATED / RELATION / AUDIT / CUSTOM.' example: BUSINESS inPlantilla: type: boolean description: Whether this field is currently part of the user's plantilla for the view. example: false bulkEditable: type: boolean description: Whether this field accepts bulk edition (FieldCapability.BULK_EDITABLE). alwaysVisible: type: boolean description: Whether the backend forces this column to be visible (FieldCapability.ALWAYS_VISIBLE_COLUMN). customFieldId: type: integer format: int64 description: Custom field id (when category = CUSTOM). StockDocument: type: object description: Stock snapshot per variant and warehouse ÔÇö read-only document. properties: id: type: string description: Composite row key (variantId_warehouseId). example: '12045_3' readOnly: true variantId: type: integer format: int64 description: Product variant (Producto) ID. example: 12045 readOnly: true warehouseId: type: integer format: int64 description: Warehouse (Sucursal) ID. example: 3 readOnly: true companyId: type: integer format: int64 description: Company ID (via warehouse). readOnly: true warehouseName: type: string description: Warehouse name. readOnly: true barcode: type: string description: Barcode. readOnly: true description: type: string description: Variant description. readOnly: true reference: type: string description: Reference. readOnly: true productName: type: string description: Product model name. readOnly: true categoryName: type: string description: Category name. readOnly: true brandName: type: string description: Brand name. readOnly: true groupName: type: string description: Group name. readOnly: true campaignName: type: string description: Campaign name. readOnly: true packQuantity: type: number description: Units per pack. readOnly: true variantEnabled: type: boolean description: Whether the variant is enabled. readOnly: true inventoriable: type: boolean description: Whether the variant is inventoriable. readOnly: true lastPurchasePrice: type: number description: Last purchase price. readOnly: true purchasePriceSystem: type: number description: System net purchase price. readOnly: true netSalePrice: type: number description: Net sale price (ex VAT). readOnly: true netSalePriceSystem: type: number description: System net sale price. readOnly: true grossSalePrice: type: number description: Gross sale price (inc VAT). readOnly: true grossSalePriceSystem: type: number description: System gross sale price. readOnly: true lastPurchaseDate: type: string description: Last purchase date (ISO 8601 with business offset). readOnly: true quantity: type: number description: On-hand quantity. readOnly: true reservedQuantity: type: number description: Reserved quantity. readOnly: true minimumStock: type: number description: Minimum stock threshold. readOnly: true inboundCount: type: number description: Inbound movement count. readOnly: true outboundCount: type: number description: Outbound movement count. readOnly: true averageCost: type: number description: Weighted average cost (PMP). readOnly: true averageCostSystem: type: number description: System weighted average cost. readOnly: true stockValueAtAverageCost: type: number description: Stock value at average cost. readOnly: true stockValueAtAverageCostSystem: type: number description: System stock value at average cost. readOnly: true lastInboundAt: type: string description: Last inbound timestamp. readOnly: true lastOutboundAt: type: string description: Last outbound timestamp. readOnly: true lastModifiedAt: type: string description: Last modification timestamp. readOnly: true FieldDescriptor: type: object description: UI-facing projection of a field catalog entry properties: apiName: type: string description: Stable API name (used in JSON, RSQL filters and AG Grid columns) example: number javaType: type: string description: Java type of the field (String, Long, BigDecimal, Date, ...) example: java.lang.String category: type: string description: 'Category: BUSINESS, CALCULATED, RELATION, AUDIT or CUSTOM. INTERNAL fields are not exposed.' example: BUSINESS label: type: string description: Default label for the field (Spanish by default) example: N├║mero group: type: string description: Logical UI group (e.g. "Identificaci├│n", "Importes") example: Identificaci├│n displayOrder: type: integer format: int32 description: Display order inside the group (lower = earlier) required: type: boolean description: Whether the field is required on create/update editable: type: boolean description: Whether the field accepts writes; calculated fields are read-only capabilities: type: array description: Capabilities the field supports (SEARCHABLE, SORTABLE, FILTERABLE, GROUPABLE, EXPORTABLE, INDEXED, AGGREGABLE, DIMENSIONABLE) items: type: string uniqueItems: true allowedFilterOperators: type: array description: RSQL/filter operators allowed on this field (EQ, NE, LT, LE, GT, GE, IN, NOT_IN, LIKE, ILIKE, IS_NULL, IS_NOT_NULL) items: type: string uniqueItems: true defaultFilterOperator: type: string description: Default filter operator when the client doesn't specify one example: EQ allowedAggregations: type: array description: Aggregation functions allowed on this field (SUM, AVG, MIN, MAX, COUNT) items: type: string uniqueItems: true uiComponent: type: string description: Suggested UI component (TEXT, NUMBER, DATE, SELECT, ...) example: TEXT alignment: type: string description: Horizontal alignment suggestion for columnar UI (LEFT, CENTER, RIGHT) example: LEFT columnWidth: type: integer format: int32 description: Suggested column width in pixels displayFormat: type: string description: Optional display format hint (e.g. currency pattern) minLength: type: integer format: int32 description: Minimum input length (null = no minimum) maxLength: type: integer format: int32 description: Maximum input length (null = no maximum) validationPattern: type: string description: Regex pattern the value must match (null = none) customFieldId: type: integer format: int64 description: Legacy custom-field id (ges_customfield.id). Present only for CUSTOM descriptors. customFieldScope: type: string description: >- Custom-field scope. MODEL = product header customFields (asociableCon=MODELO), VARIANT = product variant customFields (asociableCon=PRODUCTO), MANUFACTURING = manufacturing custom fields (asociableCon=FABRICA). JSON-backed entities (cf_definition, ADR-003) use the CfEntity name: CUSTOMER, OPTOMETRY_EXAM, AUDIOLOGY_EXAM, CONTACTOLOGY_FITTING, CONTACT_LENS_EXAM. valueType: type: string description: Legacy custom-field value type (LIBRE, NUMERICO, OPCIONES, COLOR). contentType: type: string description: Optional semantic content type (SZ, DC, MT, ...). options: type: array description: >- Available options for OPCIONES/COLOR (EAV) and small ENUM (cf_definition) custom fields. For cf_definition-backed ENUM fields the list is inlined only up to a server-side threshold; when optionCount exceeds it, this list is empty and the SPA must page/search via GET /api/v2/custom-field-definitions/{customFieldId}/options. items: $ref: '#/components/schemas/FieldOptionDescriptor' optionCount: type: integer format: int64 description: >- Total number of options of the custom field (only for cf_definition-backed ENUM descriptors). Compare with options.size() to detect that inlining was suppressed and an autocomplete over the paginated options endpoint is required. FieldOptionDescriptor: type: object description: Option metadata for a select-like field properties: id: type: integer format: int64 description: Stable option id (ges_customfield_option.id for EAV fields, cf_definition_option.id for JSON-backed fields) value: type: string description: Persisted option value (what the legacy model stores/returns) label: type: string description: Display label. Same as value unless a future source provides translations. hex: type: string description: Color hex value for COLOR custom fields enabled: type: boolean description: Whether the option is enabled PageResponseServiceLocationDocument: type: object description: Paginated response wrapper properties: data: type: array description: Items in the current page items: $ref: '#/components/schemas/ServiceLocationDocument' totalCount: type: integer format: int64 description: Total number of matching records across all pages example: 142 skip: type: integer format: int32 description: Number of records skipped to reach this page example: 0 limit: type: integer format: int32 description: Maximum records requested per page example: 50 hasMore: type: boolean description: Whether additional records exist after this page example: true PageResponseServiceCategoryDocument: type: object description: Paginated response wrapper properties: data: type: array description: Items in the current page items: $ref: '#/components/schemas/ServiceCategoryDocument' totalCount: type: integer format: int64 description: Total number of matching records across all pages example: 142 skip: type: integer format: int32 description: Number of records skipped to reach this page example: 0 limit: type: integer format: int32 description: Maximum records requested per page example: 50 hasMore: type: boolean description: Whether additional records exist after this page example: true PageResponseServiceDocument: type: object description: Paginated response wrapper properties: data: type: array description: Items in the current page items: $ref: '#/components/schemas/ServiceDocument' totalCount: type: integer format: int64 description: Total number of matching records across all pages example: 142 skip: type: integer format: int32 description: Number of records skipped to reach this page example: 0 limit: type: integer format: int32 description: Maximum records requested per page example: 50 hasMore: type: boolean description: Whether additional records exist after this page example: true PageResponseServiceBookingDocument: type: object description: Paginated response wrapper properties: data: type: array description: Items in the current page items: $ref: '#/components/schemas/ServiceBookingDocument' totalCount: type: integer format: int64 description: Total number of matching records across all pages example: 142 skip: type: integer format: int32 description: Number of records skipped to reach this page example: 0 limit: type: integer format: int32 description: Maximum records requested per page example: 50 hasMore: type: boolean description: Whether additional records exist after this page example: true FreeSlotDayDocument: type: object description: Free slots of a single calendar day. properties: date: type: string description: Calendar day in the requested timezone (YYYY-MM-DD) example: '2026-07-27' slots: type: array description: Bookable slots of that day, in chronological order items: $ref: '#/components/schemas/FreeSlotDocument' FreeSlotDocument: type: object description: A bookable time slot. properties: startAt: type: string description: Slot start (ISO 8601 with the requested timezone offset) example: '2026-07-27T09:00:00+02:00' endAt: type: string description: Slot end (ISO 8601 with the requested timezone offset) example: '2026-07-27T09:30:00+02:00' seatsAvailable: type: integer format: int32 description: Remaining seats. Always 1 outside class_booking calendars. example: 1 eligibleEmployeeIds: type: array description: Employees that could take this slot. Empty on branch calendars. items: type: integer format: int64 assignedEmployeeId: type: integer format: int64 description: Employee the slot would be assigned to on calendars that pick one (event, round_robin, service_booking). Null on the rest. FreeSlotsResponse: type: object description: Availability of a calendar over a date range, grouped by day. properties: calendarId: type: integer format: int64 description: Calendar the availability was computed for example: 2 timezone: type: string description: IANA timezone the grid was computed in ÔÇö the one that was asked for, never a server default example: Europe/Madrid startDate: type: string description: First day of the range, inclusive (YYYY-MM-DD) example: '2026-07-27' endDate: type: string description: Last day of the range, inclusive (YYYY-MM-DD) example: '2026-08-02' employeeIds: type: array description: Employees the answer was restricted to. Empty means all of them. items: type: integer format: int64 days: type: array description: One entry per requested day, in chronological order items: $ref: '#/components/schemas/FreeSlotDayDocument' totalSlots: type: integer format: int32 description: Total number of slots across the whole range example: 48 RemittanceCandidateDocument: type: object description: Remittance candidate ÔÇö pending invoice balance or installment eligible for SEPA direct debit. properties: rowKey: type: string description: >- Stable selection key used when creating a remittance. Format: {originType}-{invoiceId|installmentId} where originType is the enum {@code RemesaOrigenTipo.name()} (F or V). Opaque key ÔÇö do not derive from the {@code originType} field alone. example: V-12345 readOnly: true originType: type: string description: Source document kind ({@code RemesaOrigenTipo.name()}). F = open invoice balance, V = unpaid installment. enum: - F - V example: V readOnly: true invoiceId: type: integer format: int64 description: Issued invoice ID when the candidate is an open invoice balance readOnly: true installmentId: type: integer format: int64 description: Installment ID when the candidate is an unpaid due date readOnly: true counterpartyId: type: integer format: int64 description: Debtor customer ID readOnly: true counterpartyName: type: string description: Debtor display name readOnly: true counterpartyIban: type: string description: Masked debtor IBAN (last four characters only) example: '****5766' readOnly: true counterpartyBic: type: string description: Debtor BIC readOnly: true sepaFormat: type: string description: SEPA direct-debit scheme ({@code FormatoSepa.name()}) enum: - CORE - B2B example: CORE readOnly: true mandateSignedDate: type: string description: SEPA mandate signature date (calendar day, yyyy-MM-dd) readOnly: true mandateReference: type: string description: SEPA mandate reference (MndtId) readOnly: true signedDirectDebitOrderId: type: integer format: int64 description: Signed direct-debit order attachment ID (required for B2B) readOnly: true amount: type: number description: Amount to remit example: 150 readOnly: true baseDate: type: string description: Reference date (invoice date or installment due date) readOnly: true concept: type: string description: Human-readable concept readOnly: true PriceListValuationResponse: type: object description: Stock valuation of a branch according to a price list. properties: warehouseId: type: integer format: int64 description: Branch (sucursal) the valuation was computed for units: type: number description: Units on hand covered by the price list purchaseValue: type: number description: Stock valued at purchase price baseSaleValue: type: number description: Stock valued at the base sale price (before this price list) saleValue: type: number description: Stock valued applying this price list CatalogEntry: type: object description: Single entry of a dynamic catalog (used by AG Grid Set Filters and autocompletes). properties: id: type: integer format: int64 description: Primary key of the underlying entity (null for static enum catalogs). example: 42 code: type: string description: Business code of the entry, or the enum value for static catalogs. example: C000042 name: type: string description: Human-readable label, translated when applicable. example: Garcia applicableWhen: type: object additionalProperties: type: array items: type: string description: >- Declarative applicability constraints for a static entry. Each key is a context dimension declared by the enclosing static catalog and each value is the set of accepted wire values. Missing dimensions mean unrestricted. The SPA includes the entry only when every supplied context value belongs to its accepted set. Null for unconditional and entity-backed entries. example: documentKind: - FAC_EMI direction: - SALES attributes: type: object additionalProperties: {} description: Optional intrinsic data of the value that is not a visibility rule. Consumers may use known attributes for domain behavior but must never interpret them as generic filtering predicates. example: siiCode: '33' BulkDeleteRequest: type: object description: 'Bulk delete request: removes every id in `ids` (all-or-nothing).' properties: ids: type: array description: List of entity IDs to delete. Must not be empty. If any id is missing or outside the authenticated user's company scope, the whole operation is rolled back with HTTP 400. example: - 1 - 2 - 3 items: type: integer format: int64 BulkDeleteResponse: type: object description: 'Bulk delete response: number of entities deleted.' properties: deleted: type: integer format: int32 description: Number of entities deleted example: 3 securitySchemes: bearerAuth: type: http description: HS512 JWT issued by the legacy WAR. The same token is forwarded to the WAR from the write adapters; positions inside the JWT map to PermissionEnum (see ADR-009). scheme: bearer bearerFormat: JWT x-tagGroups: - tags: - Sales Quotes - Sales Orders - Sales Delivery Notes - Sales Invoices - Sales Credit Notes - Incoming Payments - Cash Closes - Remittances name: Sales & Transactions - tags: - Purchase Orders - Purchase Delivery Notes - Purchase Invoices - Outgoing Payments name: Purchases - tags: - Customers name: Contacts - tags: - Brands - Categories - Campaigns - Groups - Collections - Ranges - Product Lines - Product Ranges - Products - Product Variants - Price Lists - Pricing name: Catalog - tags: - Calendars - Appointments - Appointment Types - Appointment Services - Calendar Groups - Staff Schedules - Calendar Rooms - Calendar Equipments - Scheduling Calendars - Service Locations - Service Categories - Service Catalog - Service Bookings - Free Slots - Scheduling Events - Block Slots - Appointment Notes name: Scheduling - tags: - Inventory Entries - Inventory Exits - Inventory Counts - Stock name: Inventory - tags: - Optical Orders name: Operations - tags: - Vat Types - Series - Equivalence Surcharge Types - Item Types - Accounting Accounts - Activities - Journal Entries - Visit Reasons - Departments - Employee Positions - Cancellation Causes - Return Causes - Claim Causes - Claim Types - Solutions - Origin Types - Visual Therapy Templates - Card Types - Payment Terms - Payment Methods - Coupon Types - Warehouse Types - Associated Contact Types - Customer Profiles - Notes - Document Statuses - Solution Types - Loyalty Wallets - Users - User Invitations - Verifactu Configuration - Chile SII Configuration - SAT Mexico Configuration - Document Control Configuration name: Organization - tags: - Schema - Views - Catalogs - Preferences - Custom Field Definitions - Product Labels name: Platform