{
    "openapi": "3.1.0",
    "info": {
        "title": "API v1 · Sistema Facturación Perú",
        "version": "1.0.0",
        "summary": "Emite y consulta comprobantes electrónicos, guías, clientes, productos y stock de tu empresa.",
        "description": "API REST de cada empresa en `https://<tu-subdominio>.sistemafacturacionperu.com/api/v1`.\nModo pruebas (beta de SUNAT, empresa aparte, se borra a los 7 días): `https://pruebas.sistemafacturacionperu.com/api/v1`.\n\n- Autenticación: `Authorization: Bearer sfp_live_…` (o `sfp_test_…` en pruebas). Nunca en la URL (401 `clave_en_url`).\n- Éxito: `{ \"success\": true, \"data\": …, \"meta\"?: … }`. Error: `{ \"success\": false, \"code\": \"…\", \"message\": \"…\", \"errors\"?: {…} }`.\n- Todo `POST` acepta `Idempotency-Key` (recomendado): el reintento con el mismo cuerpo devuelve la misma respuesta\n  con `Idempotent-Replayed: true`.\n- Límites: 120 llamadas por minuto por clave y 30 emisiones por minuto (cabeceras `X-RateLimit-Limit` y\n  `X-RateLimit-Remaining`; al pasarte, 429 con `Retry-After`).\n- La API viene desde el Plan PRO (403 `plan_sin_api`).\n\nGuía completa: https://sistemafacturacionperu.com/desarrolladores/\n",
        "contact": {
            "name": "Sistema Facturación Perú",
            "url": "https://sistemafacturacionperu.com/desarrolladores"
        }
    },
    "servers": [
        {
            "url": "https://{subdominio}.sistemafacturacionperu.com/api/v1",
            "description": "Producción (tu empresa)",
            "variables": {
                "subdominio": {
                    "default": "miempresa"
                }
            }
        },
        {
            "url": "https://pruebas.sistemafacturacionperu.com/api/v1",
            "description": "Modo pruebas (beta de SUNAT, con una clave sfp_test_)"
        }
    ],
    "security": [
        {
            "bearer": []
        },
        {
            "conectar": []
        }
    ],
    "tags": [
        {
            "name": "Cuenta"
        },
        {
            "name": "Comprobantes",
            "description": "Factura (01), boleta (03), nota de crédito (07) y de débito (08)."
        },
        {
            "name": "Anulaciones"
        },
        {
            "name": "Cobros"
        },
        {
            "name": "Guías",
            "description": "Guía de remisión remitente (09) y transportista (31)."
        },
        {
            "name": "Otros documentos",
            "description": "Retenciones (20), percepciones (40), liquidaciones de compra (04), notas de venta y cotizaciones."
        },
        {
            "name": "Catálogo"
        },
        {
            "name": "Consultas"
        },
        {
            "name": "Webhooks"
        }
    ],
    "paths": {
        "/yo": {
            "get": {
                "tags": [
                    "Cuenta"
                ],
                "summary": "Con qué clave, usuario, local y permisos estás llamando",
                "operationId": "yo",
                "responses": {
                    "200": {
                        "description": "La clave y su contexto",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RespuestaYo"
                                },
                                "example": {
                                    "success": true,
                                    "data": {
                                        "empresa": {
                                            "ruc": "20601234567",
                                            "razon_social": "FERRETERIA LIMA S.A.C.",
                                            "nombre_comercial": "Ferre Lima"
                                        },
                                        "modo": "produccion",
                                        "sunat": "produccion",
                                        "clave": {
                                            "id": 3,
                                            "nombre": "Tienda en línea",
                                            "prefijo": "sfp_live_Ab12Cd34",
                                            "vence": null
                                        },
                                        "legacy": false,
                                        "alcances": [
                                            "comprobantes.emitir",
                                            "comprobantes.leer"
                                        ],
                                        "usuario": {
                                            "id": 1,
                                            "nombre": "Ana Torres",
                                            "tipo": "admin"
                                        },
                                        "establecimiento": {
                                            "id": 1,
                                            "codigo": "0000",
                                            "nombre": "Tienda principal"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutenticado"
                    },
                    "403": {
                        "$ref": "#/components/responses/Prohibido"
                    },
                    "423": {
                        "$ref": "#/components/responses/CuentaBloqueada"
                    },
                    "429": {
                        "$ref": "#/components/responses/DemasiadasSolicitudes"
                    }
                }
            }
        },
        "/comprobantes": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Emitir factura, boleta, nota de crédito o de débito",
                "description": "El mismo JSON de `POST /api/documents` de la API antigua, más `establecimiento`, `origen` y, en cada línea,\n`almacen_id`, `series` y `lotes` por código. Se envía a SUNAT según la configuración de la empresa (las boletas van\nen el resumen diario). Alcance `comprobantes.emitir`; función `sales.documents.create`.\n",
                "operationId": "emitirComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Comprobante"
                            },
                            "examples": {
                                "boleta": {
                                    "summary": "Boleta al contado",
                                    "value": {
                                        "serie_documento": "B001",
                                        "numero_documento": "#",
                                        "fecha_de_emision": "2026-11-03",
                                        "hora_de_emision": "10:15:00",
                                        "codigo_tipo_operacion": "0101",
                                        "codigo_tipo_documento": "03",
                                        "codigo_tipo_moneda": "PEN",
                                        "establecimiento": "0000",
                                        "datos_del_cliente_o_receptor": {
                                            "codigo_tipo_documento_identidad": "1",
                                            "numero_documento": "70123456",
                                            "apellidos_y_nombres_o_razon_social": "Ana Pérez",
                                            "codigo_pais": "PE"
                                        },
                                        "totales": {
                                            "total_operaciones_gravadas": 50.85,
                                            "total_igv": 9.15,
                                            "total_impuestos": 9.15,
                                            "total_valor": 50.85,
                                            "total_venta": 60
                                        },
                                        "items": [
                                            {
                                                "codigo_interno": "POLO-01",
                                                "descripcion": "Polo azul talla M",
                                                "unidad_de_medida": "NIU",
                                                "cantidad": 2,
                                                "valor_unitario": 25.42,
                                                "codigo_tipo_precio": "01",
                                                "precio_unitario": 30,
                                                "codigo_tipo_afectacion_igv": "10",
                                                "total_base_igv": 50.85,
                                                "porcentaje_igv": 18,
                                                "total_igv": 9.15,
                                                "total_impuestos": 9.15,
                                                "total_valor_item": 50.85,
                                                "total_item": 60
                                            }
                                        ],
                                        "pagos": [
                                            {
                                                "codigo_metodo_pago": "01",
                                                "codigo_destino_pago": "cash",
                                                "monto": 60
                                            }
                                        ]
                                    }
                                },
                                "factura_desde_cotizacion": {
                                    "summary": "Factura que convierte la cotización 15",
                                    "value": {
                                        "serie_documento": "F001",
                                        "numero_documento": "#",
                                        "fecha_de_emision": "2026-11-03",
                                        "hora_de_emision": "10:15:00",
                                        "codigo_tipo_operacion": "0101",
                                        "codigo_tipo_documento": "01",
                                        "codigo_tipo_moneda": "PEN",
                                        "origen": {
                                            "tipo": "cotizacion",
                                            "id": 15
                                        },
                                        "datos_del_cliente_o_receptor": {
                                            "codigo_tipo_documento_identidad": "6",
                                            "numero_documento": "20601234567",
                                            "apellidos_y_nombres_o_razon_social": "CONSTRUCTORA ANDINA S.A.C.",
                                            "codigo_pais": "PE",
                                            "ubigeo": "150101",
                                            "direccion": "Av. Lima 123"
                                        },
                                        "totales": {
                                            "total_operaciones_gravadas": 1000,
                                            "total_igv": 180,
                                            "total_impuestos": 180,
                                            "total_valor": 1000,
                                            "total_venta": 1180
                                        },
                                        "items": [
                                            {
                                                "codigo_interno": "CEM-42",
                                                "descripcion": "Cemento 42.5 kg",
                                                "unidad_de_medida": "NIU",
                                                "cantidad": 40,
                                                "valor_unitario": 25,
                                                "codigo_tipo_precio": "01",
                                                "precio_unitario": 29.5,
                                                "codigo_tipo_afectacion_igv": "10",
                                                "total_base_igv": 1000,
                                                "porcentaje_igv": 18,
                                                "total_igv": 180,
                                                "total_impuestos": 180,
                                                "total_valor_item": 1000,
                                                "total_item": 1180,
                                                "lotes": [
                                                    {
                                                        "codigo": "L-2026-10",
                                                        "cantidad": 40
                                                    }
                                                ]
                                            }
                                        ],
                                        "codigo_condicion_de_pago": "02",
                                        "cuotas": [
                                            {
                                                "fecha": "2026-12-03",
                                                "codigo_tipo_moneda": "PEN",
                                                "monto": 1180
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Emitido",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/ComprobanteEmitido"
                                        }
                                    }
                                },
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 1520,
                                        "external_id": "6f1c7d0e-8f7e-4a1c-9d5b-2a2f8e1c9b10",
                                        "tipo": "03",
                                        "serie": "B001",
                                        "numero": 845,
                                        "numero_completo": "B001-845",
                                        "fecha_emision": "2026-11-03",
                                        "hora_emision": "10:15:00",
                                        "establecimiento_id": 1,
                                        "moneda": "PEN",
                                        "total": 60,
                                        "cliente": {
                                            "tipo_documento": "1",
                                            "numero_documento": "70123456",
                                            "nombre": "Ana Pérez"
                                        },
                                        "estado": {
                                            "codigo": "01",
                                            "clave": "registrado",
                                            "descripcion": "Registrado"
                                        },
                                        "sunat": null,
                                        "hash": "k2y5S1y3O2Q8+1u7p5h0Lw==",
                                        "enlaces": {
                                            "pdf": "https://miempresa.sistemafacturacionperu.com/api/v1/comprobantes/1520/pdf",
                                            "pdf_ticket": "https://miempresa.sistemafacturacionperu.com/api/v1/comprobantes/1520/pdf?formato=ticket",
                                            "xml": "https://miempresa.sistemafacturacionperu.com/api/v1/comprobantes/1520/xml",
                                            "cdr": null
                                        },
                                        "enlaces_publicos": {
                                            "pdf": "https://miempresa.sistemafacturacionperu.com/downloads/document/pdf/6f1c7d0e-8f7e-4a1c-9d5b-2a2f8e1c9b10",
                                            "xml": "https://miempresa.sistemafacturacionperu.com/downloads/document/xml/6f1c7d0e-8f7e-4a1c-9d5b-2a2f8e1c9b10",
                                            "cdr": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/PeticionInvalida"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutenticado"
                    },
                    "403": {
                        "$ref": "#/components/responses/Prohibido"
                    },
                    "409": {
                        "$ref": "#/components/responses/Idempotencia"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    },
                    "423": {
                        "$ref": "#/components/responses/CuentaBloqueada"
                    },
                    "429": {
                        "$ref": "#/components/responses/DemasiadasSolicitudes"
                    },
                    "500": {
                        "$ref": "#/components/responses/ErrorInterno"
                    }
                }
            },
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Listar comprobantes (paginado)",
                "description": "Un usuario que no ve toda la empresa (por ejemplo, un vendedor) ve solo los suyos. Alcance `comprobantes.leer`.",
                "operationId": "listarComprobantes",
                "parameters": [
                    {
                        "name": "desde",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "hasta",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "01",
                                "03",
                                "07",
                                "08"
                            ]
                        }
                    },
                    {
                        "name": "serie",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "numero",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "description": "Clave (registrado, enviado, aceptado, observado, rechazado, anulado, por_anular) o código SUNAT",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cliente_numero",
                        "in": "query",
                        "description": "RUC o DNI del cliente",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página de comprobantes",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ComprobanteEmitido"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutenticado"
                    },
                    "403": {
                        "$ref": "#/components/responses/Prohibido"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/comprobantes/buscar": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Buscar por serie y número",
                "operationId": "buscarComprobante",
                "parameters": [
                    {
                        "name": "serie",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "F001"
                    },
                    {
                        "name": "numero",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        },
                        "example": 120
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "01",
                                "03",
                                "07",
                                "08"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/UnComprobante"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/comprobantes/{id}": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Consultar un comprobante (por id o external_id)",
                "operationId": "verComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/UnComprobante"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/comprobantes/{id}/pdf": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Descargar el PDF",
                "description": "Alcance `comprobantes.leer`; función `sales.documents.export`.",
                "operationId": "pdfComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "name": "formato",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "a4",
                                "a5",
                                "ticket",
                                "ticket_58",
                                "ticket_50"
                            ],
                            "default": "a4"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "PDF",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "503": {
                        "$ref": "#/components/responses/NoDisponible"
                    }
                }
            }
        },
        "/comprobantes/{id}/xml": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Descargar el XML firmado",
                "operationId": "xmlComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "XML firmado",
                        "content": {
                            "application/xml": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/comprobantes/{id}/cdr": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Descargar la constancia de SUNAT (CDR, zip)",
                "operationId": "cdrComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "CDR",
                        "content": {
                            "application/zip": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Aún sin CDR (`cdr_no_disponible`) o no existe",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/comprobantes/{id}/anular": {
            "post": {
                "tags": [
                    "Anulaciones"
                ],
                "summary": "Anular (el sistema elige baja o resumen)",
                "description": "Factura y sus notas → comunicación de baja; boleta y sus notas → resumen diario de anulación. Solo comprobantes\naceptados u observados. Devuelve el ticket de SUNAT. Alcance `comprobantes.anular`; función `sales.documents.void`.\n",
                "operationId": "anularComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "motivo"
                                ],
                                "properties": {
                                    "motivo": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 100
                                    }
                                }
                            },
                            "example": {
                                "motivo": "Error en el precio"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Anulación enviada; consulta el ticket",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Anulacion"
                                        }
                                    }
                                },
                                "example": {
                                    "success": true,
                                    "data": {
                                        "tipo": "baja",
                                        "ticket": "1730646000123",
                                        "external_id": "a1b2…",
                                        "estado": {
                                            "codigo": "03",
                                            "clave": "enviado",
                                            "descripcion": "Enviado"
                                        },
                                        "consultar": "https://miempresa.sistemafacturacionperu.com/api/v1/anulaciones/1730646000123"
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/anulaciones/{ticket}": {
            "get": {
                "tags": [
                    "Anulaciones"
                ],
                "summary": "Estado de una baja o resumen de anulación (consulta a SUNAT)",
                "operationId": "estadoAnulacion",
                "parameters": [
                    {
                        "name": "ticket",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Estado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Anulacion"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/comprobantes/{id}/reenviar-sunat": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Reenviar una factura (o su nota) registrada a SUNAT",
                "description": "Las boletas van en el resumen diario (422 `va_en_resumen`). Función `sales.sunat_status.manage`.",
                "operationId": "reenviarSunat",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/UnComprobante"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/comprobantes/{id}/enviar": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "summary": "Enviar por correo o por el WhatsApp de tu empresa",
                "description": "WhatsApp sale SOLO por la línea propia de tu empresa (Canales › WhatsApp), nunca por la de la plataforma.",
                "operationId": "enviarComprobante",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "canal",
                                    "destino"
                                ],
                                "properties": {
                                    "canal": {
                                        "type": "string",
                                        "enum": [
                                            "correo",
                                            "whatsapp"
                                        ]
                                    },
                                    "destino": {
                                        "type": "string",
                                        "description": "Correo (hasta 5, separados por coma) o celular de 9 dígitos"
                                    },
                                    "mensaje": {
                                        "type": "string",
                                        "maxLength": 500
                                    }
                                }
                            },
                            "examples": {
                                "correo": {
                                    "value": {
                                        "canal": "correo",
                                        "destino": "compras@cliente.pe"
                                    }
                                },
                                "whatsapp": {
                                    "value": {
                                        "canal": "whatsapp",
                                        "destino": "987654321"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Enviado",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "enviado": true,
                                        "canal": "whatsapp",
                                        "destino": "51987654321",
                                        "mensaje": "Enviado por WhatsApp a 987 654 321 (Mi línea)."
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    },
                    "502": {
                        "description": "El proveedor de correo o WhatsApp falló (`envio_fallido`)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/comprobantes/{id}/cobros": {
            "get": {
                "tags": [
                    "Cobros"
                ],
                "summary": "Cobros y saldo pendiente",
                "operationId": "verCobros",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Saldo",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Saldo"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Cobros"
                ],
                "summary": "Registrar un cobro",
                "description": "Por el mismo servicio de la web (Por cobrar › Registrar cobro): un medio que no es efectivo va a una cuenta de cobro\n(`cuenta_cobro_id`, banco o billetera del tipo del medio) y con N.° de operación. Alcance `cobros.registrar`;\nfunción `finance.payments.create`.\n",
                "operationId": "registrarCobro",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "fecha",
                                    "monto",
                                    "medio"
                                ],
                                "properties": {
                                    "fecha": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "monto": {
                                        "type": "number",
                                        "exclusiveMinimum": 0
                                    },
                                    "medio": {
                                        "type": "string",
                                        "description": "Código del medio de pago (01 efectivo, 005 transferencia, …)"
                                    },
                                    "cuenta_cobro_id": {
                                        "type": "integer",
                                        "description": "Cuenta de banco o billetera (sin ella: la caja)"
                                    },
                                    "referencia": {
                                        "type": "string",
                                        "description": "N.° de operación"
                                    },
                                    "fecha_operacion": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "cuota_id": {
                                        "type": "integer"
                                    }
                                }
                            },
                            "example": {
                                "fecha": "2026-11-03",
                                "monto": 590,
                                "medio": "005",
                                "cuenta_cobro_id": 2,
                                "referencia": "OP-778812"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Cobro registrado y saldo",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "allOf": [
                                                {
                                                    "$ref": "#/components/schemas/Saldo"
                                                },
                                                {
                                                    "type": "object",
                                                    "properties": {
                                                        "cobro_id": {
                                                            "type": "integer"
                                                        }
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/guias": {
            "post": {
                "tags": [
                    "Guías"
                ],
                "summary": "Emitir guía (crea, envía y consulta en una llamada)",
                "description": "El JSON de `POST /api/dispatches`. Si SUNAT aún no responde el ticket, el estado es `pendiente`: consulta con\n`GET /guias/{id}`. Alcance `guias.emitir`; funciones `sales.dispatches.create` y `sales.dispatches.emit`.\n",
                "operationId": "emitirGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Guia"
                            },
                            "example": {
                                "serie_documento": "T001",
                                "numero_documento": "#",
                                "fecha_de_emision": "2026-11-03",
                                "hora_de_emision": "09:00:00",
                                "codigo_tipo_documento": "09",
                                "datos_del_cliente_o_receptor": {
                                    "codigo_tipo_documento_identidad": "6",
                                    "numero_documento": "20601234567",
                                    "apellidos_y_nombres_o_razon_social": "CONSTRUCTORA ANDINA S.A.C."
                                },
                                "codigo_modo_transporte": "02",
                                "codigo_motivo_traslado": "01",
                                "fecha_de_traslado": "2026-11-03",
                                "peso_total": 1000,
                                "unidad_peso_total": "KGM",
                                "direccion_partida": {
                                    "ubigeo": "150101",
                                    "direccion": "Av. Lima 123",
                                    "codigo_del_domicilio_fiscal": "0000"
                                },
                                "direccion_llegada": {
                                    "ubigeo": "150132",
                                    "direccion": "Jr. Las Obras 456",
                                    "codigo_del_domicilio_fiscal": "0000"
                                },
                                "chofer": {
                                    "codigo_tipo_documento_identidad": "1",
                                    "numero_documento": "40123456",
                                    "nombres": "Luis Quispe",
                                    "numero_licencia": "Q40123456"
                                },
                                "vehiculo": {
                                    "numero_de_placa": "ABC123"
                                },
                                "items": [
                                    {
                                        "codigo_interno": "CEM-42",
                                        "descripcion": "Cemento 42.5 kg",
                                        "unidad_de_medida": "NIU",
                                        "cantidad": 40
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Guía creada (aceptada o pendiente)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/GuiaEmitida"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            },
            "get": {
                "tags": [
                    "Guías"
                ],
                "summary": "Listar guías",
                "operationId": "listarGuias",
                "parameters": [
                    {
                        "name": "desde",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "hasta",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "09",
                                "31"
                            ]
                        }
                    },
                    {
                        "name": "serie",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "numero",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "registrado, pendiente, aceptado, rechazado…"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página de guías",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/GuiaEmitida"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/guias/{id}": {
            "get": {
                "tags": [
                    "Guías"
                ],
                "summary": "Consultar una guía (si está pendiente, consulta el ticket en SUNAT)",
                "operationId": "verGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "La guía",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/GuiaEmitida"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/guias/{id}/enviar": {
            "post": {
                "tags": [
                    "Guías"
                ],
                "summary": "Reintentar el envío de una guía registrada",
                "operationId": "enviarGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "La guía",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/GuiaEmitida"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    }
                }
            }
        },
        "/guias/{id}/pdf": {
            "get": {
                "tags": [
                    "Guías"
                ],
                "summary": "PDF de la guía",
                "operationId": "pdfGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "PDF",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/guias/{id}/xml": {
            "get": {
                "tags": [
                    "Guías"
                ],
                "summary": "XML firmado de la guía",
                "operationId": "xmlGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "XML",
                        "content": {
                            "application/xml": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/guias/{id}/cdr": {
            "get": {
                "tags": [
                    "Guías"
                ],
                "summary": "CDR de la guía",
                "operationId": "cdrGuia",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdDocumento"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "CDR",
                        "content": {
                            "application/zip": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/retenciones": {
            "post": {
                "tags": [
                    "Otros documentos"
                ],
                "summary": "Emitir comprobante de retención (20)",
                "description": "El JSON de `POST /api/retentions`. Función `sales.advanced_documents.create`.",
                "operationId": "emitirRetencion",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonApiAntigua"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/OtroCpe"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/percepciones": {
            "post": {
                "tags": [
                    "Otros documentos"
                ],
                "summary": "Emitir comprobante de percepción (40)",
                "description": "El JSON de `POST /api/perceptions`.",
                "operationId": "emitirPercepcion",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonApiAntigua"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/OtroCpe"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/liquidaciones-compra": {
            "post": {
                "tags": [
                    "Otros documentos"
                ],
                "summary": "Emitir liquidación de compra (04)",
                "description": "El JSON de `POST /api/purchase-settlements`.",
                "operationId": "emitirLiquidacion",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonApiAntigua"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/OtroCpe"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/notas-venta": {
            "post": {
                "tags": [
                    "Otros documentos"
                ],
                "summary": "Registrar nota de venta",
                "description": "Con el JSON de los comprobantes (sin `codigo_tipo_documento`), `serie_documento` de notas de venta (NV01…) y\n`origen` cotización o pedido. Para facturarla después: `POST /comprobantes` con `origen: {tipo: nota_venta, id}`.\nFunción `sales.sale_notes.create`.\n",
                "operationId": "registrarNotaVenta",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Comprobante"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/Borrador"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/cotizaciones": {
            "post": {
                "tags": [
                    "Otros documentos"
                ],
                "summary": "Registrar cotización",
                "description": "Con el JSON de los comprobantes, sin serie; `fecha_de_vencimiento`, `fecha_de_entrega` y `observaciones` opcionales.",
                "operationId": "registrarCotizacion",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Comprobante"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "$ref": "#/components/responses/Borrador"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/clientes": {
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Listar clientes",
                "operationId": "listarClientes",
                "parameters": [
                    {
                        "name": "buscar",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Cliente"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Crear cliente",
                "operationId": "crearCliente",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ClienteEntrada"
                            },
                            "example": {
                                "tipo_documento": "6",
                                "numero_documento": "20601234567",
                                "nombre": "BODEGA LIMA S.A.C.",
                                "direccion": "Av. Lima 1",
                                "ubigeo": "150101",
                                "correo": "compras@bodega.pe"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Creado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Cliente"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/clientes/{numero}": {
            "parameters": [
                {
                    "name": "numero",
                    "in": "path",
                    "required": true,
                    "description": "RUC, DNI u otro documento",
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Consultar cliente por número de documento",
                "operationId": "verCliente",
                "responses": {
                    "200": {
                        "description": "Cliente",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Cliente"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            },
            "put": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Cambiar datos del cliente (el documento no cambia)",
                "operationId": "cambiarCliente",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ClienteEntrada"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Cliente",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Cliente"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/productos": {
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Listar productos",
                "operationId": "listarProductos",
                "parameters": [
                    {
                        "name": "buscar",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Producto"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Crear producto (nace sin stock)",
                "operationId": "crearProducto",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ProductoEntrada"
                            },
                            "example": {
                                "codigo_interno": "CAF-01",
                                "descripcion": "Café 250 g",
                                "precio_unitario": 18.5,
                                "unidad_de_medida": "NIU",
                                "codigo_tipo_afectacion_igv": "10"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Creado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Producto"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    }
                }
            }
        },
        "/productos/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Id o código interno",
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Consultar producto",
                "operationId": "verProducto",
                "responses": {
                    "200": {
                        "description": "Producto",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Producto"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            },
            "put": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Cambiar producto (cambiar el precio pide catalog.items.prices.update)",
                "operationId": "cambiarProducto",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ProductoEntrada"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Producto",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Producto"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/stock": {
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Stock por almacén, lote y serie",
                "description": "Alcance `stock.leer`; función `inventory.read`.",
                "operationId": "verStock",
                "parameters": [
                    {
                        "name": "producto",
                        "in": "query",
                        "description": "Id o código interno",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "almacen",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Stock",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Stock"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                },
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "producto_id": 12,
                                            "codigo_interno": "POLO-01",
                                            "descripcion": "Polo azul",
                                            "control_de_stock": true,
                                            "stock_total": 10,
                                            "almacenes": [
                                                {
                                                    "almacen_id": 1,
                                                    "almacen": "Almacén Lima",
                                                    "establecimiento": "0000",
                                                    "stock": 7
                                                },
                                                {
                                                    "almacen_id": 2,
                                                    "almacen": "Almacén Arequipa",
                                                    "establecimiento": "0001",
                                                    "stock": 3
                                                }
                                            ],
                                            "lotes": [
                                                {
                                                    "codigo": "L-01",
                                                    "cantidad": 5,
                                                    "vence": "2027-01-31",
                                                    "almacen_id": 1
                                                }
                                            ],
                                            "series": [
                                                {
                                                    "numero": "SN-1",
                                                    "almacen_id": 1
                                                }
                                            ]
                                        }
                                    ],
                                    "meta": {
                                        "page": 1,
                                        "per_page": 20,
                                        "total": 1,
                                        "last_page": 1
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/establecimientos": {
            "get": {
                "tags": [
                    "Catálogo"
                ],
                "summary": "Locales con sus series y almacenes",
                "operationId": "listarEstablecimientos",
                "responses": {
                    "200": {
                        "description": "Locales",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "id": 1,
                                            "codigo": "0000",
                                            "nombre": "Tienda principal",
                                            "direccion": "Av. Lima 123",
                                            "ubigeo": "150101",
                                            "series": [
                                                {
                                                    "tipo": "01",
                                                    "serie": "F001"
                                                },
                                                {
                                                    "tipo": "03",
                                                    "serie": "B001"
                                                },
                                                {
                                                    "tipo": "09",
                                                    "serie": "T001"
                                                }
                                            ],
                                            "almacenes": [
                                                {
                                                    "id": 1,
                                                    "nombre": "Almacén Lima",
                                                    "principal": true
                                                }
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/consultas/ruc/{numero}": {
            "get": {
                "tags": [
                    "Consultas"
                ],
                "summary": "Consulta RUC (SUNAT)",
                "operationId": "consultaRuc",
                "parameters": [
                    {
                        "name": "numero",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^(10|15|16|17|20)\\d{9}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Datos del RUC",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "ruc": "20601234567",
                                        "razon_social": "BODEGA LIMA S.A.C.",
                                        "nombre_comercial": null,
                                        "direccion": "AV. LIMA 1",
                                        "ubigeo": "150101",
                                        "estado": "ACTIVO",
                                        "condicion": "HABIDO",
                                        "agente_de_retencion": false
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "502": {
                        "$ref": "#/components/responses/NoDisponible"
                    }
                }
            }
        },
        "/consultas/dni/{numero}": {
            "get": {
                "tags": [
                    "Consultas"
                ],
                "summary": "Consulta DNI (RENIEC)",
                "operationId": "consultaDni",
                "parameters": [
                    {
                        "name": "numero",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^\\d{8}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Datos del DNI",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "dni": "70123456",
                                        "nombre": "PEREZ GOMEZ ANA",
                                        "nombres": "ANA",
                                        "apellido_paterno": "PEREZ",
                                        "apellido_materno": "GOMEZ",
                                        "direccion": null,
                                        "ubigeo": null
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/consultas/tipo-cambio": {
            "get": {
                "tags": [
                    "Consultas"
                ],
                "summary": "Tipo de cambio SUNAT",
                "operationId": "tipoCambio",
                "parameters": [
                    {
                        "name": "fecha",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tipo de cambio",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "fecha": "2026-11-03",
                                        "compra": 3.712,
                                        "venta": 3.741
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/webhooks": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Listar webhooks",
                "operationId": "listarWebhooks",
                "responses": {
                    "200": {
                        "description": "Webhooks y eventos disponibles",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Webhook"
                                            }
                                        },
                                        "meta": {
                                            "type": "object",
                                            "properties": {
                                                "eventos_disponibles": {
                                                    "type": "object"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Crear webhook (el secreto se muestra una vez)",
                "operationId": "crearWebhook",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "url",
                                    "eventos"
                                ],
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "https y dominio público"
                                    },
                                    "eventos": {
                                        "type": "array",
                                        "items": {
                                            "$ref": "#/components/schemas/Evento"
                                        }
                                    },
                                    "descripcion": {
                                        "type": "string"
                                    }
                                }
                            },
                            "example": {
                                "url": "https://mi-sistema.pe/avisos-sfp",
                                "eventos": [
                                    "comprobante.aceptado",
                                    "comprobante.rechazado"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Creado",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "id": 4,
                                        "url": "https://mi-sistema.pe/avisos-sfp",
                                        "eventos": [
                                            "comprobante.aceptado",
                                            "comprobante.rechazado"
                                        ],
                                        "activo": true,
                                        "secreto": "whsec_9fK2…",
                                        "aviso": "Guarda el secreto ahora: no se vuelve a mostrar."
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ReglaDeNegocio"
                    }
                }
            }
        },
        "/webhooks/{id}": {
            "delete": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Borrar webhook",
                "operationId": "borrarWebhook",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Borrado",
                        "content": {
                            "application/json": {
                                "example": {
                                    "success": true,
                                    "data": {
                                        "borrado": true,
                                        "id": 4
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    }
                }
            }
        },
        "/webhooks/{id}/entregas": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Entregas de un webhook",
                "operationId": "entregasWebhook",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pendiente",
                                "reintentando",
                                "entregado",
                                "fallido"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Entregas",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Entrega"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/Meta"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/webhooks/entregas/{id}/reenviar": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "summary": "Reenviar una entrega",
                "operationId": "reenviarEntrega",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "responses": {
                    "202": {
                        "description": "En cola",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "success": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Entrega"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "webhooks": {
        "aviso": {
            "post": {
                "summary": "Aviso de un cambio de estado SUNAT",
                "description": "Cabeceras: `X-SFP-Signature: t=<unix>,v1=<hex HMAC-SHA256(secreto, \"t.cuerpo\")>`, `X-SFP-Delivery: <uuid>`,\n`X-SFP-Event: <evento>`. Responde 2xx en menos de 10 s; si no, reintentamos a los 1 m, 5 m, 30 m, 2 h, 6 h y 24 h.\nNo seguimos redirecciones.\n",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Aviso"
                            },
                            "example": {
                                "id": "0b8f3c1e-2d4a-4f7e-9a61-6c5d2e1f0a9b",
                                "evento": "comprobante.aceptado",
                                "creado": "2026-11-03T10:15:09-05:00",
                                "data": {
                                    "tipo_documento": "comprobante",
                                    "id": 1520,
                                    "external_id": "6f1c7d0e-8f7e-4a1c-9d5b-2a2f8e1c9b10",
                                    "tipo": "01",
                                    "numero_completo": "F001-120",
                                    "fecha_emision": "2026-11-03",
                                    "total": 1180,
                                    "moneda": "PEN",
                                    "estado": {
                                        "codigo": "05",
                                        "clave": "aceptado",
                                        "descripcion": "Aceptado"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Recibido"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Clave `sfp_live_<40>` (o `sfp_test_<40>` en pruebas). El token antiguo del usuario también vale (todos los alcances)."
            },
            "conectar": {
                "type": "oauth2",
                "description": "«Conectar con Sistema Facturación Perú» (https://sistemafacturacionperu.com/desarrolladores/conectar/): el cliente de tu sistema conecta su cuenta con\nun botón. El token de acceso `sfp_oat_<48>` va en `Authorization: Bearer` y vale 1 hora, solo en la API de SU\nempresa (`empresa.api_url` de la respuesta del token). PKCE S256 y `state` obligatorios. En el Plan Básico solo\nsirven los alcances de emitir: lo demás responde 403 `plan_insuficiente` (con `errors.plan`).\n",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://api.sistemafacturacionperu.com/conectar",
                        "tokenUrl": "https://api.sistemafacturacionperu.com/oauth/token",
                        "refreshUrl": "https://api.sistemafacturacionperu.com/oauth/token",
                        "scopes": {
                            "comprobantes.emitir": "Emitir facturas, boletas, notas, notas de venta, cotizaciones, retenciones, percepciones y liquidaciones de compra",
                            "comprobantes.leer": "Ver tus comprobantes y descargar su PDF, XML y CDR",
                            "comprobantes.anular": "Anular comprobantes",
                            "guias.emitir": "Emitir guías de remisión",
                            "guias.leer": "Ver tus guías de remisión y descargar sus archivos",
                            "cobros.registrar": "Registrar cobros (desde PRO)",
                            "catalogo.leer": "Ver clientes, productos y locales (desde PRO)",
                            "catalogo.escribir": "Crear y cambiar clientes y productos (desde PRO)",
                            "stock.leer": "Ver el stock (desde PRO)",
                            "consultas": "Consultar RUC, DNI y tipo de cambio",
                            "webhooks.gestionar": "Crear y borrar webhooks (desde PRO)"
                        }
                    }
                }
            }
        },
        "parameters": {
            "IdempotencyKey": {
                "name": "Idempotency-Key",
                "in": "header",
                "description": "Hasta 255 caracteres visibles (un UUID). Se recuerda 24 h.",
                "schema": {
                    "type": "string",
                    "maxLength": 255
                }
            },
            "IdDocumento": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "Id numérico o external_id (UUID)",
                "schema": {
                    "type": "string"
                }
            },
            "Page": {
                "name": "page",
                "in": "query",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1
                }
            },
            "PerPage": {
                "name": "per_page",
                "in": "query",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 20
                }
            }
        },
        "responses": {
            "UnComprobante": {
                "description": "El comprobante",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "success": {
                                    "const": true
                                },
                                "data": {
                                    "$ref": "#/components/schemas/ComprobanteEmitido"
                                }
                            }
                        }
                    }
                }
            },
            "OtroCpe": {
                "description": "Emitido",
                "content": {
                    "application/json": {
                        "example": {
                            "success": true,
                            "data": {
                                "id": 33,
                                "external_id": "c3…",
                                "tipo": "20",
                                "numero_completo": "R001-33",
                                "fecha_emision": "2026-11-03",
                                "estado": {
                                    "codigo": "05",
                                    "clave": "aceptado",
                                    "descripcion": "Aceptado"
                                },
                                "sunat": {
                                    "codigo": "0",
                                    "descripcion": "El Comprobante numero R001-33, ha sido aceptado",
                                    "notas": []
                                },
                                "enlaces_publicos": {
                                    "pdf": "…",
                                    "xml": "…",
                                    "cdr": "…"
                                }
                            }
                        }
                    }
                }
            },
            "Borrador": {
                "description": "Registrado",
                "content": {
                    "application/json": {
                        "example": {
                            "success": true,
                            "data": {
                                "id": 88,
                                "external_id": "d4…",
                                "tipo": "80",
                                "numero_completo": "NV01-88",
                                "fecha_emision": "2026-11-03",
                                "moneda": "PEN",
                                "total": 60,
                                "estado": {
                                    "codigo": "01",
                                    "clave": "registrado",
                                    "descripcion": "Registrado"
                                },
                                "enlaces_publicos": {
                                    "pdf": "…/sale-notes/print/d4…/a4",
                                    "pdf_ticket": "…/ticket"
                                }
                            }
                        }
                    }
                }
            },
            "PeticionInvalida": {
                "description": "JSON inválido (`json_invalido`) o Idempotency-Key mal formada (`idempotencia_invalida`)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "NoAutenticado": {
                "description": "`clave_invalida`, `clave_revocada`, `clave_vencida`, `clave_en_url`, `clave_de_pruebas`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "code": "clave_revocada",
                            "message": "Esta clave fue revocada. Crea otra en Configuración › Sistema › Integraciones › API."
                        }
                    }
                }
            },
            "Prohibido": {
                "description": "`scope_faltante` (con la cabecera X-SFP-Scope-Required), `sin_permiso`, `plan_sin_api`, `establecimiento_no_permitido`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "success": false,
                            "code": "scope_faltante",
                            "message": "Esta clave no tiene el permiso «comprobantes.emitir» (Emitir facturas, boletas…). Crea una clave con ese permiso."
                        }
                    }
                }
            },
            "NoEncontrado": {
                "description": "`no_encontrado`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Conflicto": {
                "description": "`duplicado`, `ya_anulado`, `no_reenviable`, `conflicto`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Idempotencia": {
                "description": "`idempotencia_distinta` (otra petición con la misma clave) o `idempotencia_en_proceso`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "ReglaDeNegocio": {
                "description": "Validación (`validacion`, con `errors` por campo) o una regla del negocio con su código (ver el catálogo de la guía).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "validacion": {
                                "value": {
                                    "success": false,
                                    "code": "validacion",
                                    "message": "Revisa los datos enviados.",
                                    "errors": {
                                        "totales.total_venta": [
                                            "El campo totales.total venta es obligatorio."
                                        ]
                                    }
                                }
                            },
                            "detraccion": {
                                "value": {
                                    "success": false,
                                    "code": "detraccion_minimo",
                                    "message": "Sin detracción: el código 037 aplica a ventas mayores a S/ 700.00, y esta es de S/ 600.00. …",
                                    "errors": {
                                        "detraccion": [
                                            "…"
                                        ]
                                    }
                                }
                            },
                            "limite": {
                                "value": {
                                    "success": false,
                                    "code": "limite_plan",
                                    "message": "Ha superado el límite permitido para la emisión de comprobantes"
                                }
                            }
                        }
                    }
                }
            },
            "CuentaBloqueada": {
                "description": "`cuenta_bloqueada`: pago vencido o cuenta suspendida",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "DemasiadasSolicitudes": {
                "description": "`demasiadas_solicitudes` o `demasiadas_emisiones`, con Retry-After",
                "headers": {
                    "Retry-After": {
                        "schema": {
                            "type": "integer"
                        }
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "NoDisponible": {
                "description": "`archivo_no_disponible`, `consulta_no_disponible`, `no_disponible`",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "ErrorInterno": {
                "description": "`error_interno` (sin detalles; la clave de idempotencia queda libre para reintentar)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "success",
                    "code",
                    "message"
                ],
                "properties": {
                    "success": {
                        "const": false
                    },
                    "code": {
                        "type": "string",
                        "description": "Código estable (ver el catálogo de errores)"
                    },
                    "message": {
                        "type": "string",
                        "description": "En español, para mostrar"
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Meta": {
                "type": "object",
                "properties": {
                    "page": {
                        "type": "integer"
                    },
                    "per_page": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "last_page": {
                        "type": "integer"
                    }
                }
            },
            "Estado": {
                "type": "object",
                "properties": {
                    "codigo": {
                        "type": "string",
                        "description": "state_type_id: 01 registrado, 03 enviado, 05 aceptado, 07 observado, 09 rechazado, 11 anulado, 13 por anular"
                    },
                    "clave": {
                        "type": "string",
                        "enum": [
                            "registrado",
                            "enviado",
                            "pendiente",
                            "aceptado",
                            "observado",
                            "rechazado",
                            "anulado",
                            "por_anular",
                            "desconocido"
                        ]
                    },
                    "descripcion": {
                        "type": "string"
                    }
                }
            },
            "Sunat": {
                "type": [
                    "object",
                    "null"
                ],
                "properties": {
                    "codigo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "descripcion": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notas": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "RespuestaYo": {
                "type": "object",
                "properties": {
                    "success": {
                        "const": true
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "empresa": {
                                "type": "object"
                            },
                            "modo": {
                                "type": "string",
                                "enum": [
                                    "produccion",
                                    "pruebas"
                                ]
                            },
                            "sunat": {
                                "type": "string",
                                "enum": [
                                    "produccion",
                                    "beta",
                                    "interno"
                                ]
                            },
                            "clave": {
                                "type": "object"
                            },
                            "legacy": {
                                "type": "boolean"
                            },
                            "alcances": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/Alcance"
                                }
                            },
                            "usuario": {
                                "type": "object"
                            },
                            "establecimiento": {
                                "type": [
                                    "object",
                                    "null"
                                ]
                            }
                        }
                    }
                }
            },
            "Alcance": {
                "type": "string",
                "enum": [
                    "comprobantes.emitir",
                    "comprobantes.leer",
                    "comprobantes.anular",
                    "guias.emitir",
                    "guias.leer",
                    "cobros.registrar",
                    "catalogo.leer",
                    "catalogo.escribir",
                    "stock.leer",
                    "consultas",
                    "webhooks.gestionar"
                ]
            },
            "Origen": {
                "type": "object",
                "required": [
                    "tipo",
                    "id"
                ],
                "properties": {
                    "tipo": {
                        "type": "string",
                        "enum": [
                            "cotizacion",
                            "pedido",
                            "nota_venta",
                            "guia"
                        ]
                    },
                    "id": {
                        "type": "integer"
                    }
                }
            },
            "Linea": {
                "type": "object",
                "required": [
                    "descripcion",
                    "unidad_de_medida",
                    "cantidad",
                    "valor_unitario",
                    "precio_unitario",
                    "codigo_tipo_afectacion_igv",
                    "total_item"
                ],
                "properties": {
                    "codigo_interno": {
                        "type": "string",
                        "description": "Con control de stock, el producto debe existir (422 producto_no_existe)"
                    },
                    "descripcion": {
                        "type": "string"
                    },
                    "unidad_de_medida": {
                        "type": "string",
                        "example": "NIU"
                    },
                    "cantidad": {
                        "type": "number"
                    },
                    "valor_unitario": {
                        "type": "number"
                    },
                    "codigo_tipo_precio": {
                        "type": "string",
                        "example": "01"
                    },
                    "precio_unitario": {
                        "type": "number"
                    },
                    "codigo_tipo_afectacion_igv": {
                        "type": "string",
                        "example": "10"
                    },
                    "total_base_igv": {
                        "type": "number"
                    },
                    "porcentaje_igv": {
                        "type": "number"
                    },
                    "total_igv": {
                        "type": "number"
                    },
                    "total_impuestos": {
                        "type": "number"
                    },
                    "total_valor_item": {
                        "type": "number"
                    },
                    "total_item": {
                        "type": "number"
                    },
                    "almacen_id": {
                        "type": "integer",
                        "description": "Almacén del local del que sale"
                    },
                    "series": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Números de serie (tantas como la cantidad)"
                    },
                    "lotes": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "codigo",
                                "cantidad"
                            ],
                            "properties": {
                                "codigo": {
                                    "type": "string"
                                },
                                "cantidad": {
                                    "type": "number"
                                }
                            }
                        }
                    },
                    "actualizar_descripcion": {
                        "type": "boolean",
                        "default": true
                    }
                }
            },
            "Comprobante": {
                "type": "object",
                "required": [
                    "serie_documento",
                    "numero_documento",
                    "fecha_de_emision",
                    "hora_de_emision",
                    "codigo_tipo_documento",
                    "codigo_tipo_moneda",
                    "datos_del_cliente_o_receptor",
                    "totales",
                    "items"
                ],
                "properties": {
                    "serie_documento": {
                        "type": "string",
                        "example": "F001"
                    },
                    "numero_documento": {
                        "type": "string",
                        "description": "'#' = el siguiente correlativo"
                    },
                    "fecha_de_emision": {
                        "type": "string",
                        "format": "date"
                    },
                    "hora_de_emision": {
                        "type": "string",
                        "example": "10:15:00"
                    },
                    "codigo_tipo_documento": {
                        "type": "string",
                        "enum": [
                            "01",
                            "03",
                            "07",
                            "08"
                        ]
                    },
                    "codigo_tipo_operacion": {
                        "type": "string",
                        "description": "0101 venta interna; 1001 sujeta a detracción; 1004 transporte de carga…"
                    },
                    "codigo_tipo_moneda": {
                        "type": "string",
                        "example": "PEN"
                    },
                    "factor_tipo_de_cambio": {
                        "type": "number"
                    },
                    "fecha_de_vencimiento": {
                        "type": "string",
                        "format": "date"
                    },
                    "establecimiento": {
                        "type": "string",
                        "description": "Código SUNAT del local (GET /establecimientos)"
                    },
                    "origen": {
                        "$ref": "#/components/schemas/Origen"
                    },
                    "datos_del_cliente_o_receptor": {
                        "type": "object",
                        "required": [
                            "codigo_tipo_documento_identidad",
                            "numero_documento",
                            "apellidos_y_nombres_o_razon_social"
                        ],
                        "properties": {
                            "codigo_tipo_documento_identidad": {
                                "type": "string",
                                "description": "1 DNI, 6 RUC, 4 carné de extranjería, 7 pasaporte, 0 otros"
                            },
                            "numero_documento": {
                                "type": "string"
                            },
                            "apellidos_y_nombres_o_razon_social": {
                                "type": "string"
                            },
                            "codigo_pais": {
                                "type": "string"
                            },
                            "ubigeo": {
                                "type": "string"
                            },
                            "direccion": {
                                "type": "string"
                            },
                            "correo_electronico": {
                                "type": "string"
                            },
                            "telefono": {
                                "type": "string"
                            }
                        }
                    },
                    "totales": {
                        "type": "object",
                        "required": [
                            "total_venta"
                        ],
                        "properties": {
                            "total_anticipos": {
                                "type": "number"
                            },
                            "total_descuentos": {
                                "type": "number"
                            },
                            "total_cargos": {
                                "type": "number"
                            },
                            "total_exportacion": {
                                "type": "number"
                            },
                            "total_operaciones_gravadas": {
                                "type": "number"
                            },
                            "total_operaciones_inafectas": {
                                "type": "number"
                            },
                            "total_operaciones_exoneradas": {
                                "type": "number"
                            },
                            "total_operaciones_gratuitas": {
                                "type": "number"
                            },
                            "total_igv": {
                                "type": "number"
                            },
                            "total_impuestos_bolsa_plastica": {
                                "type": "number"
                            },
                            "total_impuestos": {
                                "type": "number"
                            },
                            "total_valor": {
                                "type": "number"
                            },
                            "subtotal_venta": {
                                "type": "number"
                            },
                            "total_venta": {
                                "type": "number"
                            }
                        }
                    },
                    "items": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                            "$ref": "#/components/schemas/Linea"
                        }
                    },
                    "pagos": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "codigo_metodo_pago",
                                "codigo_destino_pago",
                                "monto"
                            ],
                            "properties": {
                                "codigo_metodo_pago": {
                                    "type": "string"
                                },
                                "codigo_destino_pago": {
                                    "type": [
                                        "string",
                                        "integer"
                                    ],
                                    "description": "'cash' o el id de la cuenta de cobro"
                                },
                                "referencia": {
                                    "type": "string"
                                },
                                "monto": {
                                    "type": "number"
                                }
                            }
                        }
                    },
                    "codigo_condicion_de_pago": {
                        "type": "string",
                        "description": "01 contado, 02 crédito"
                    },
                    "cuotas": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "fecha",
                                "codigo_tipo_moneda",
                                "monto"
                            ],
                            "properties": {
                                "fecha": {
                                    "type": "string",
                                    "format": "date"
                                },
                                "codigo_tipo_moneda": {
                                    "type": "string"
                                },
                                "monto": {
                                    "type": "number"
                                },
                                "codigo_metodo_de_pago": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "detraccion": {
                        "type": "object",
                        "description": "Mínimo por código y sin retención (422 detraccion_minimo, detraccion_con_retencion, detraccion_operacion, detraccion_codigo)",
                        "properties": {
                            "codigo_tipo_detraccion": {
                                "type": "string"
                            },
                            "porcentaje": {
                                "type": "number"
                            },
                            "monto": {
                                "type": "number"
                            },
                            "codigo_metodo_pago": {
                                "type": "string"
                            },
                            "cuenta_bancaria": {
                                "type": "string"
                            }
                        }
                    },
                    "retencion": {
                        "type": "object",
                        "properties": {
                            "codigo": {
                                "type": "string"
                            },
                            "porcentaje": {
                                "type": "number"
                            },
                            "monto": {
                                "type": "number"
                            },
                            "base": {
                                "type": "number"
                            }
                        }
                    },
                    "percepcion": {
                        "type": "object",
                        "properties": {
                            "codigo": {
                                "type": "string"
                            },
                            "porcentaje": {
                                "type": "number"
                            },
                            "monto": {
                                "type": "number"
                            },
                            "base": {
                                "type": "number"
                            }
                        }
                    },
                    "anticipos": {
                        "type": "array",
                        "description": "Cada anticipo debe tener saldo (422 anticipo_sin_saldo)",
                        "items": {
                            "type": "object",
                            "properties": {
                                "numero": {
                                    "type": "string",
                                    "example": "F001-25"
                                },
                                "codigo_tipo_documento": {
                                    "type": "string"
                                },
                                "monto": {
                                    "type": "number"
                                },
                                "total": {
                                    "type": "number"
                                }
                            }
                        }
                    },
                    "guias": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "numero": {
                                    "type": "string"
                                },
                                "codigo_tipo_documento": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "documento_afectado": {
                        "type": "object",
                        "description": "Notas: external_id, o serie_documento + numero_documento + codigo_tipo_documento"
                    },
                    "codigo_tipo_nota": {
                        "type": "string"
                    },
                    "motivo_o_sustento_de_nota": {
                        "type": "string"
                    },
                    "acciones": {
                        "type": "object",
                        "properties": {
                            "enviar_email": {
                                "type": "boolean"
                            },
                            "enviar_xml_firmado": {
                                "type": "boolean"
                            },
                            "formato_pdf": {
                                "type": "string"
                            }
                        }
                    },
                    "informacion_adicional": {
                        "type": "string"
                    }
                }
            },
            "ComprobanteEmitido": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "external_id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "tipo": {
                        "type": "string"
                    },
                    "serie": {
                        "type": "string"
                    },
                    "numero": {
                        "type": "integer"
                    },
                    "numero_completo": {
                        "type": "string"
                    },
                    "fecha_emision": {
                        "type": "string",
                        "format": "date"
                    },
                    "hora_emision": {
                        "type": "string"
                    },
                    "establecimiento_id": {
                        "type": "integer"
                    },
                    "moneda": {
                        "type": "string"
                    },
                    "total": {
                        "type": "number"
                    },
                    "cliente": {
                        "type": "object",
                        "properties": {
                            "tipo_documento": {
                                "type": "string"
                            },
                            "numero_documento": {
                                "type": "string"
                            },
                            "nombre": {
                                "type": "string"
                            }
                        }
                    },
                    "estado": {
                        "$ref": "#/components/schemas/Estado"
                    },
                    "sunat": {
                        "$ref": "#/components/schemas/Sunat"
                    },
                    "hash": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "enlaces": {
                        "type": "object",
                        "properties": {
                            "pdf": {
                                "type": "string"
                            },
                            "pdf_ticket": {
                                "type": "string"
                            },
                            "xml": {
                                "type": "string"
                            },
                            "cdr": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        }
                    },
                    "enlaces_publicos": {
                        "type": "object",
                        "description": "Descargas públicas por external_id (para tu cliente)"
                    },
                    "avisos": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "Anulacion": {
                "type": "object",
                "properties": {
                    "tipo": {
                        "type": "string",
                        "enum": [
                            "baja",
                            "resumen"
                        ]
                    },
                    "ticket": {
                        "type": "string"
                    },
                    "external_id": {
                        "type": "string"
                    },
                    "estado": {
                        "$ref": "#/components/schemas/Estado"
                    },
                    "sunat": {
                        "$ref": "#/components/schemas/Sunat"
                    },
                    "comprobante": {
                        "$ref": "#/components/schemas/ComprobanteEmitido"
                    },
                    "consultar": {
                        "type": "string"
                    }
                }
            },
            "Saldo": {
                "type": "object",
                "properties": {
                    "comprobante_id": {
                        "type": "integer"
                    },
                    "numero_completo": {
                        "type": "string"
                    },
                    "moneda": {
                        "type": "string"
                    },
                    "total": {
                        "type": "number"
                    },
                    "notas_de_credito": {
                        "type": "number"
                    },
                    "cobrado": {
                        "type": "number"
                    },
                    "por_confirmar": {
                        "type": "number"
                    },
                    "saldo_pendiente": {
                        "type": "number"
                    },
                    "cobros": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "integer"
                                },
                                "fecha": {
                                    "type": "string"
                                },
                                "monto": {
                                    "type": "number"
                                },
                                "medio": {
                                    "type": "string"
                                },
                                "referencia": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "confirmado": {
                                    "type": "boolean"
                                }
                            }
                        }
                    }
                }
            },
            "Guia": {
                "type": "object",
                "description": "El JSON de POST /api/dispatches (API antigua) + `establecimiento`, `origen` (cotizacion o pedido) y líneas con `almacen_id`.",
                "required": [
                    "serie_documento",
                    "numero_documento",
                    "fecha_de_emision",
                    "hora_de_emision",
                    "codigo_tipo_documento",
                    "fecha_de_traslado",
                    "peso_total",
                    "unidad_peso_total",
                    "direccion_partida",
                    "direccion_llegada",
                    "items"
                ],
                "properties": {
                    "codigo_tipo_documento": {
                        "type": "string",
                        "enum": [
                            "09",
                            "31"
                        ]
                    },
                    "establecimiento": {
                        "type": "string"
                    },
                    "origen": {
                        "$ref": "#/components/schemas/Origen"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "codigo_interno",
                                "descripcion",
                                "cantidad"
                            ],
                            "properties": {
                                "codigo_interno": {
                                    "type": "string"
                                },
                                "descripcion": {
                                    "type": "string"
                                },
                                "cantidad": {
                                    "type": "number"
                                },
                                "almacen_id": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                },
                "additionalProperties": true
            },
            "GuiaEmitida": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "external_id": {
                        "type": "string"
                    },
                    "tipo": {
                        "type": "string"
                    },
                    "serie": {
                        "type": "string"
                    },
                    "numero": {
                        "type": "integer"
                    },
                    "numero_completo": {
                        "type": "string"
                    },
                    "fecha_emision": {
                        "type": "string"
                    },
                    "fecha_traslado": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "estado": {
                        "$ref": "#/components/schemas/Estado"
                    },
                    "ticket": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sunat": {
                        "$ref": "#/components/schemas/Sunat"
                    },
                    "enlaces": {
                        "type": "object"
                    },
                    "avisos": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "JsonApiAntigua": {
                "type": "object",
                "description": "El mismo JSON documentado en la API antigua para este comprobante (+ `establecimiento`).",
                "additionalProperties": true
            },
            "Cliente": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "tipo_documento": {
                        "type": "string"
                    },
                    "numero_documento": {
                        "type": "string"
                    },
                    "nombre": {
                        "type": "string"
                    },
                    "nombre_comercial": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "direccion": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "ubigeo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "codigo_pais": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "correo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "telefono": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "activo": {
                        "type": "boolean"
                    }
                }
            },
            "ClienteEntrada": {
                "type": "object",
                "properties": {
                    "tipo_documento": {
                        "type": "string",
                        "enum": [
                            "0",
                            "1",
                            "4",
                            "6",
                            "7",
                            "A",
                            "B"
                        ]
                    },
                    "numero_documento": {
                        "type": "string"
                    },
                    "nombre": {
                        "type": "string"
                    },
                    "nombre_comercial": {
                        "type": "string"
                    },
                    "direccion": {
                        "type": "string"
                    },
                    "ubigeo": {
                        "type": "string"
                    },
                    "codigo_pais": {
                        "type": "string"
                    },
                    "correo": {
                        "type": "string",
                        "format": "email"
                    },
                    "telefono": {
                        "type": "string"
                    }
                }
            },
            "Producto": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "codigo_interno": {
                        "type": "string"
                    },
                    "descripcion": {
                        "type": "string"
                    },
                    "nombre": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "unidad_de_medida": {
                        "type": "string"
                    },
                    "tipo": {
                        "type": "string"
                    },
                    "moneda": {
                        "type": "string"
                    },
                    "precio_unitario": {
                        "type": "number"
                    },
                    "codigo_tipo_afectacion_igv": {
                        "type": "string"
                    },
                    "incluye_igv": {
                        "type": "boolean"
                    },
                    "codigo_producto_sunat": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "stock": {
                        "type": "number"
                    },
                    "lotes": {
                        "type": "boolean"
                    },
                    "series": {
                        "type": "boolean"
                    },
                    "activo": {
                        "type": "boolean"
                    }
                }
            },
            "ProductoEntrada": {
                "type": "object",
                "properties": {
                    "codigo_interno": {
                        "type": "string"
                    },
                    "descripcion": {
                        "type": "string"
                    },
                    "nombre": {
                        "type": "string"
                    },
                    "unidad_de_medida": {
                        "type": "string"
                    },
                    "tipo": {
                        "type": "string",
                        "enum": [
                            "01",
                            "02"
                        ]
                    },
                    "moneda": {
                        "type": "string",
                        "enum": [
                            "PEN",
                            "USD"
                        ]
                    },
                    "precio_unitario": {
                        "type": "number"
                    },
                    "codigo_tipo_afectacion_igv": {
                        "type": "string"
                    },
                    "incluye_igv": {
                        "type": "boolean"
                    },
                    "codigo_producto_sunat": {
                        "type": "string"
                    },
                    "activo": {
                        "type": "boolean"
                    }
                }
            },
            "Stock": {
                "type": "object",
                "properties": {
                    "producto_id": {
                        "type": "integer"
                    },
                    "codigo_interno": {
                        "type": "string"
                    },
                    "descripcion": {
                        "type": "string"
                    },
                    "control_de_stock": {
                        "type": "boolean"
                    },
                    "stock_total": {
                        "type": "number"
                    },
                    "almacenes": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "almacen_id": {
                                    "type": "integer"
                                },
                                "almacen": {
                                    "type": "string"
                                },
                                "establecimiento": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "stock": {
                                    "type": "number"
                                }
                            }
                        }
                    },
                    "lotes": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "codigo": {
                                    "type": "string"
                                },
                                "cantidad": {
                                    "type": "number"
                                },
                                "vence": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "almacen_id": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ]
                                }
                            }
                        }
                    },
                    "series": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "numero": {
                                    "type": "string"
                                },
                                "almacen_id": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "Evento": {
                "type": "string",
                "enum": [
                    "comprobante.aceptado",
                    "comprobante.observado",
                    "comprobante.rechazado",
                    "comprobante.anulado",
                    "guia.aceptada",
                    "guia.rechazada",
                    "resumen.procesado"
                ]
            },
            "Webhook": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "url": {
                        "type": "string"
                    },
                    "eventos": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Evento"
                        }
                    },
                    "descripcion": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "activo": {
                        "type": "boolean"
                    },
                    "ultima_entrega": {
                        "type": [
                            "object",
                            "null"
                        ]
                    },
                    "creado": {
                        "type": "string"
                    }
                }
            },
            "Entrega": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "uuid": {
                        "type": "string"
                    },
                    "webhook_id": {
                        "type": "integer"
                    },
                    "evento": {
                        "$ref": "#/components/schemas/Evento"
                    },
                    "estado": {
                        "type": "string",
                        "enum": [
                            "pendiente",
                            "reintentando",
                            "entregado",
                            "fallido"
                        ]
                    },
                    "intentos": {
                        "type": "integer"
                    },
                    "codigo_respuesta": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "error": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "proximo_intento": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "entregado": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "creado": {
                        "type": "string"
                    }
                }
            },
            "Aviso": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Igual a X-SFP-Delivery: úsalo para no procesar dos veces"
                    },
                    "evento": {
                        "$ref": "#/components/schemas/Evento"
                    },
                    "creado": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "data": {
                        "type": "object"
                    }
                }
            }
        }
    }
}
