{
    "openapi": "3.1.0",
    "info": {
        "title": "Nodiq e-CF API",
        "version": "1.0.0",
        "summary": "Facturación electrónica (e-CF) para República Dominicana.",
        "description": "API REST de Nodiq e-CF, Proveedor de Servicios de Facturación Electrónica (PSFE) ante la DGII.\n\nAutenticación: `Authorization: Bearer nq_test_...` (práctica/pre-certificación) o `nq_live_...` (producción). Límite: 120 peticiones por minuto por clave. Errores: `{\"error\":{\"codigo\",\"mensaje\",\"detalles\":[{\"campo\",\"mensaje\"}]}}`.\n\nWebhooks firmados: cabecera `Nodiq-Firma: t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>`; eventos documento.creado, documento.aceptado, documento.aceptado_condicional, documento.rechazado, documento.anulado, documento.aprobacion_comercial, recibido.nuevo, secuencia.por_agotarse, certificado.por_vencer; 9 reintentos durante ~72 h.\n\nDocumentación: https://ecf.nodiqtech.com/docs",
        "contact": {
            "name": "Soporte Nodiq Tech",
            "email": "soporte@nodiqtech.com",
            "url": "https://ecf.nodiqtech.com/soporte"
        },
        "termsOfService": "https://ecf.nodiqtech.com/legal/terminos"
    },
    "servers": [
        {
            "url": "https://ecf.nodiqtech.com/api/v1",
            "description": "Producción y pruebas (el ambiente lo decide la clave)"
        }
    ],
    "security": [
        {
            "bearer": []
        }
    ],
    "tags": [
        {
            "name": "Comprobantes",
            "description": "Emisión y consulta de e-CF."
        },
        {
            "name": "Recibidos",
            "description": "e-CF recibidos de proveedores y aprobación comercial."
        },
        {
            "name": "Clientes"
        },
        {
            "name": "Secuencias"
        },
        {
            "name": "Contribuyentes"
        },
        {
            "name": "Estado"
        }
    ],
    "paths": {
        "/comprobantes": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "crearComprobante",
                "summary": "Crear, firmar y emitir un comprobante",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        },
                        "description": "Repetir la misma clave devuelve el mismo resultado sin emitir dos veces."
                    },
                    {
                        "name": "validar",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Prueba en seco: valida y calcula sin consumir e-NCF ni enviar a la DGII."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ComprobanteNuevo"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Comprobante creado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Comprobante"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "Resultado de la validación en seco (?validar=true)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Validacion"
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "422": {
                        "$ref": "#/components/responses/Validacion"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            },
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "listarComprobantes",
                "summary": "Listar comprobantes",
                "parameters": [
                    {
                        "name": "estado",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "aceptado",
                                "aceptado_condicional",
                                "rechazado",
                                "en_proceso",
                                "contingencia",
                                "firmado",
                                "error",
                                "anulado"
                            ]
                        }
                    },
                    {
                        "name": "tipo",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "enum": [
                                31,
                                32,
                                33,
                                34,
                                41,
                                43,
                                44,
                                45,
                                46,
                                47
                            ]
                        }
                    },
                    {
                        "name": "desde",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "hasta",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    },
                    {
                        "name": "por_pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Listado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "datos": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Comprobante"
                                            }
                                        },
                                        "paginacion": {
                                            "$ref": "#/components/schemas/Paginacion"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/comprobantes/{id}": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "obtenerComprobante",
                "summary": "Obtener un comprobante",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Comprobante",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Comprobante"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/comprobantes/{id}/pdf": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "pdfComprobante",
                "summary": "Representación impresa (PDF)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "PDF",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/comprobantes/{id}/xml": {
            "get": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "xmlComprobante",
                "summary": "XML firmado",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "XML",
                        "content": {
                            "application/xml": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/comprobantes/{id}/reenviar": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "reenviarComprobante",
                "summary": "Reintentar el envío a la DGII",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Comprobante actualizado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Comprobante"
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/comprobantes/{id}/correo": {
            "post": {
                "tags": [
                    "Comprobantes"
                ],
                "operationId": "enviarCorreo",
                "summary": "Enviar el comprobante por correo",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "para"
                                ],
                                "properties": {
                                    "para": {
                                        "type": "string",
                                        "description": "Uno o varios correos separados por coma."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Correo en cola",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Ok"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/Validacion"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/recibidos": {
            "get": {
                "tags": [
                    "Recibidos"
                ],
                "operationId": "listarRecibidos",
                "summary": "Listar comprobantes recibidos",
                "parameters": [
                    {
                        "name": "aprobacion",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pendiente",
                                "aprobado",
                                "rechazado"
                            ]
                        }
                    },
                    {
                        "name": "rnc_emisor",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "desde",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "hasta",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    },
                    {
                        "name": "por_pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Listado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "datos": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Recibido"
                                            }
                                        },
                                        "paginacion": {
                                            "$ref": "#/components/schemas/Paginacion"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/recibidos/{id}": {
            "get": {
                "tags": [
                    "Recibidos"
                ],
                "operationId": "obtenerRecibido",
                "summary": "Obtener un recibido",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Recibido",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Recibido"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/recibidos/{id}/aprobar": {
            "post": {
                "tags": [
                    "Recibidos"
                ],
                "operationId": "aprobarRecibido",
                "summary": "Aprobación comercial",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Recibido actualizado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Recibido"
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/recibidos/{id}/rechazar": {
            "post": {
                "tags": [
                    "Recibidos"
                ],
                "operationId": "rechazarRecibido",
                "summary": "Rechazo comercial",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador del recurso."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "motivo"
                                ],
                                "properties": {
                                    "motivo": {
                                        "type": "string",
                                        "maxLength": 250
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Recibido actualizado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Recibido"
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflicto"
                    },
                    "422": {
                        "$ref": "#/components/responses/Validacion"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/clientes": {
            "get": {
                "tags": [
                    "Clientes"
                ],
                "operationId": "listarClientes",
                "summary": "Listar clientes",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Busca por nombre o RNC."
                    },
                    {
                        "name": "pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    },
                    {
                        "name": "por_pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Listado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "datos": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Cliente"
                                            }
                                        },
                                        "paginacion": {
                                            "$ref": "#/components/schemas/Paginacion"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            },
            "post": {
                "tags": [
                    "Clientes"
                ],
                "operationId": "crearCliente",
                "summary": "Crear un cliente",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Comprador"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Cliente creado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Cliente"
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/Validacion"
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/secuencias": {
            "get": {
                "tags": [
                    "Secuencias"
                ],
                "operationId": "listarSecuencias",
                "summary": "Secuencias de e-NCF autorizadas",
                "responses": {
                    "200": {
                        "description": "Secuencias",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "datos": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Secuencia"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/contribuyentes/{rnc}": {
            "get": {
                "tags": [
                    "Contribuyentes"
                ],
                "operationId": "consultarContribuyente",
                "summary": "Consultar el padrón de la DGII",
                "parameters": [
                    {
                        "name": "rnc",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9]{9}([0-9]{2})?$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Contribuyente",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Contribuyente"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        },
        "/estado": {
            "get": {
                "tags": [
                    "Estado"
                ],
                "operationId": "estado",
                "summary": "Salud del servicio y de la clave",
                "responses": {
                    "200": {
                        "description": "Estado",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "ok": {
                                            "type": "boolean"
                                        },
                                        "ambiente": {
                                            "type": "string"
                                        },
                                        "empresa": {
                                            "type": "object",
                                            "properties": {
                                                "rnc": {
                                                    "type": "string"
                                                },
                                                "razon_social": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "dgii": {
                                            "type": "string",
                                            "enum": [
                                                "operativo",
                                                "degradado",
                                                "interrumpido"
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NoAutorizado"
                    },
                    "404": {
                        "$ref": "#/components/responses/NoEncontrado"
                    },
                    "429": {
                        "$ref": "#/components/responses/Limite"
                    }
                }
            }
        }
    },
    "webhooks": {
        "documento.creado": {
            "post": {
                "summary": "Se creó y firmó un comprobante.",
                "operationId": "webhook_documento_creado",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "documento.aceptado": {
            "post": {
                "summary": "La DGII aceptó el comprobante.",
                "operationId": "webhook_documento_aceptado",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "documento.aceptado_condicional": {
            "post": {
                "summary": "La DGII lo aceptó con observaciones.",
                "operationId": "webhook_documento_aceptado_condicional",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "documento.rechazado": {
            "post": {
                "summary": "La DGII lo rechazó.",
                "operationId": "webhook_documento_rechazado",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "documento.anulado": {
            "post": {
                "summary": "Se anuló el comprobante o su secuencia.",
                "operationId": "webhook_documento_anulado",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "documento.aprobacion_comercial": {
            "post": {
                "summary": "El comprador aprobó o rechazó comercialmente el comprobante.",
                "operationId": "webhook_documento_aprobacion_comercial",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "recibido.nuevo": {
            "post": {
                "summary": "Llegó un e-CF de un proveedor.",
                "operationId": "webhook_recibido_nuevo",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "secuencia.por_agotarse": {
            "post": {
                "summary": "Quedan pocos e-NCF o la secuencia está por vencer.",
                "operationId": "webhook_secuencia_por_agotarse",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        },
        "certificado.por_vencer": {
            "post": {
                "summary": "El certificado digital vence en menos de 30 días.",
                "operationId": "webhook_certificado_por_vencer",
                "parameters": [
                    {
                        "name": "Nodiq-Evento",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Nodiq-Entrega",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Identificador único de la entrega."
                    },
                    {
                        "name": "Nodiq-Firma",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "t=<unix>,v1=<hex HMAC-SHA256(secreto, t + \".\" + cuerpo)>"
                    }
                ],
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Evento"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Responde 2xx en menos de 10 s. Si no, se reintenta 9 veces durante ~72 h."
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Clave de API: nq_test_... o nq_live_..."
            }
        },
        "responses": {
            "NoAutorizado": {
                "description": "Clave ausente, inválida o revocada",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "NoEncontrado": {
                "description": "El recurso no existe",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Conflicto": {
                "description": "Conflicto de estado o de idempotencia",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Validacion": {
                "description": "Error de validación",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Limite": {
                "description": "Se superó el límite de 120 peticiones por minuto",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "error"
                ],
                "properties": {
                    "error": {
                        "type": "object",
                        "required": [
                            "mensaje"
                        ],
                        "properties": {
                            "codigo": {
                                "type": "string",
                                "examples": [
                                    "validacion"
                                ]
                            },
                            "mensaje": {
                                "type": "string"
                            },
                            "detalles": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "campo": {
                                            "type": "string"
                                        },
                                        "mensaje": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "Ok": {
                "type": "object",
                "properties": {
                    "ok": {
                        "type": "boolean"
                    },
                    "mensaje": {
                        "type": "string"
                    }
                }
            },
            "Paginacion": {
                "type": "object",
                "properties": {
                    "pagina": {
                        "type": "integer"
                    },
                    "por_pagina": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "paginas": {
                        "type": "integer"
                    }
                }
            },
            "Comprador": {
                "type": "object",
                "description": "rnc (RNC o cédula) o extranjero.",
                "properties": {
                    "rnc": {
                        "type": "string",
                        "pattern": "^[0-9]{9}([0-9]{2})?$"
                    },
                    "extranjero": {
                        "type": "string"
                    },
                    "razon_social": {
                        "type": "string",
                        "maxLength": 150
                    },
                    "correo": {
                        "type": "string",
                        "format": "email"
                    },
                    "direccion": {
                        "type": "string",
                        "maxLength": 100
                    },
                    "municipio": {
                        "type": "string",
                        "description": "Código DGII de 6 dígitos."
                    },
                    "provincia": {
                        "type": "string",
                        "description": "Código DGII de 6 dígitos."
                    },
                    "pais": {
                        "type": "string"
                    }
                }
            },
            "LineaNueva": {
                "type": "object",
                "required": [
                    "nombre",
                    "cantidad",
                    "precio",
                    "indicador",
                    "tipo"
                ],
                "properties": {
                    "nombre": {
                        "type": "string",
                        "maxLength": 80
                    },
                    "descripcion": {
                        "type": "string",
                        "maxLength": 1000
                    },
                    "cantidad": {
                        "type": "number",
                        "exclusiveMinimum": 0
                    },
                    "precio": {
                        "type": "number",
                        "minimum": 0
                    },
                    "indicador": {
                        "type": "integer",
                        "enum": [
                            0,
                            1,
                            2,
                            3,
                            4
                        ],
                        "description": "0 no facturable, 1 ITBIS 18 %, 2 ITBIS 16 %, 3 ITBIS 0 %, 4 exento."
                    },
                    "descuento": {
                        "type": "number",
                        "minimum": 0
                    },
                    "codigo": {
                        "type": "string",
                        "maxLength": 35
                    },
                    "unidad": {
                        "type": "integer",
                        "description": "Código de unidad de medida DGII (43 = unidad)."
                    },
                    "tipo": {
                        "type": "integer",
                        "enum": [
                            1,
                            2
                        ],
                        "description": "1 bien, 2 servicio."
                    },
                    "retencion_itbis_pct": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                    },
                    "retencion_isr_pct": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                    }
                }
            },
            "ComprobanteNuevo": {
                "type": "object",
                "required": [
                    "tipo",
                    "lineas",
                    "tipo_pago"
                ],
                "properties": {
                    "tipo": {
                        "type": "integer",
                        "enum": [
                            31,
                            32,
                            33,
                            34,
                            41,
                            43,
                            44,
                            45,
                            46,
                            47
                        ]
                    },
                    "fecha_emision": {
                        "type": "string",
                        "format": "date"
                    },
                    "cliente_id": {
                        "type": "integer"
                    },
                    "comprador": {
                        "$ref": "#/components/schemas/Comprador"
                    },
                    "lineas": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 1000,
                        "items": {
                            "$ref": "#/components/schemas/LineaNueva"
                        }
                    },
                    "tipo_pago": {
                        "type": "integer",
                        "enum": [
                            1,
                            2,
                            3
                        ],
                        "description": "1 contado, 2 crédito, 3 gratuito."
                    },
                    "fecha_limite_pago": {
                        "type": "string",
                        "format": "date"
                    },
                    "formas_pago": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "forma",
                                "monto"
                            ],
                            "properties": {
                                "forma": {
                                    "type": "integer",
                                    "enum": [
                                        1,
                                        2,
                                        3,
                                        4,
                                        5,
                                        6,
                                        7,
                                        8
                                    ]
                                },
                                "monto": {
                                    "type": "number",
                                    "format": "double"
                                }
                            }
                        }
                    },
                    "moneda": {
                        "type": "string",
                        "default": "DOP",
                        "minLength": 3,
                        "maxLength": 3
                    },
                    "tasa_cambio": {
                        "type": "number",
                        "exclusiveMinimum": 0
                    },
                    "tipo_ingresos": {
                        "type": "string",
                        "enum": [
                            "01",
                            "02",
                            "03",
                            "04",
                            "05",
                            "06"
                        ],
                        "default": "01"
                    },
                    "precios_con_itbis": {
                        "type": "boolean",
                        "default": false
                    },
                    "referencia": {
                        "type": "object",
                        "description": "Obligatoria en 33 y 34.",
                        "required": [
                            "encf",
                            "fecha",
                            "codigo"
                        ],
                        "properties": {
                            "encf": {
                                "type": "string"
                            },
                            "fecha": {
                                "type": "string",
                                "format": "date"
                            },
                            "codigo": {
                                "type": "integer",
                                "enum": [
                                    1,
                                    2,
                                    3,
                                    4,
                                    5
                                ]
                            },
                            "razon": {
                                "type": "string",
                                "maxLength": 90
                            }
                        }
                    },
                    "referencia_externa": {
                        "type": "string",
                        "maxLength": 100
                    },
                    "notas": {
                        "type": "string"
                    }
                }
            },
            "Totales": {
                "type": "object",
                "properties": {
                    "gravado": {
                        "type": "number",
                        "format": "double"
                    },
                    "exento": {
                        "type": "number",
                        "format": "double"
                    },
                    "itbis": {
                        "type": "number",
                        "format": "double"
                    },
                    "total": {
                        "type": "number",
                        "format": "double"
                    },
                    "itbis_retenido": {
                        "type": "number",
                        "format": "double"
                    },
                    "isr_retenido": {
                        "type": "number",
                        "format": "double"
                    }
                }
            },
            "Validacion": {
                "type": "object",
                "properties": {
                    "valido": {
                        "type": "boolean"
                    },
                    "totales": {
                        "$ref": "#/components/schemas/Totales"
                    },
                    "advertencias": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "Comprobante": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Identificador único (26 caracteres)."
                    },
                    "encf": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "tipo": {
                        "type": "integer",
                        "enum": [
                            31,
                            32,
                            33,
                            34,
                            41,
                            43,
                            44,
                            45,
                            46,
                            47
                        ]
                    },
                    "tipo_nombre": {
                        "type": "string"
                    },
                    "estado": {
                        "type": "string",
                        "enum": [
                            "aceptado",
                            "aceptado_condicional",
                            "rechazado",
                            "en_proceso",
                            "contingencia",
                            "firmado",
                            "error",
                            "anulado"
                        ]
                    },
                    "ambiente": {
                        "type": "string",
                        "enum": [
                            "Simulado",
                            "TesteCF",
                            "CerteCF",
                            "eCF"
                        ]
                    },
                    "rfce": {
                        "type": "boolean",
                        "description": "Factura de consumo informada por resumen (RFCE)."
                    },
                    "fecha_emision": {
                        "type": "string",
                        "format": "date"
                    },
                    "fecha_limite_pago": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "comprador": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/Comprador"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "moneda": {
                        "type": "string"
                    },
                    "tasa_cambio": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "totales": {
                        "$ref": "#/components/schemas/Totales"
                    },
                    "lineas": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "numero": {
                                    "type": "integer"
                                },
                                "nombre": {
                                    "type": "string"
                                },
                                "descripcion": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "cantidad": {
                                    "type": "number"
                                },
                                "precio": {
                                    "type": "number"
                                },
                                "descuento": {
                                    "type": "number"
                                },
                                "indicador": {
                                    "type": "integer"
                                },
                                "monto": {
                                    "type": "number",
                                    "format": "double"
                                },
                                "itbis": {
                                    "type": "number",
                                    "format": "double"
                                }
                            }
                        }
                    },
                    "referencia": {
                        "type": [
                            "object",
                            "null"
                        ]
                    },
                    "codigo_seguridad": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "fecha_firma": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "track_id": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "contingencia": {
                        "type": "boolean"
                    },
                    "mensajes_dgii": {
                        "type": "array",
                        "items": []
                    },
                    "aprobacion_comercial": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "pendiente",
                            "aprobado",
                            "rechazado",
                            null
                        ]
                    },
                    "referencia_externa": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url_publica": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "url_pdf": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "url_xml": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "url_qr": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "origen": {
                        "type": "string",
                        "enum": [
                            "web",
                            "api",
                            "importacion"
                        ]
                    },
                    "creado": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "actualizado": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Recibido": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "encf": {
                        "type": "string"
                    },
                    "tipo": {
                        "type": "integer"
                    },
                    "emisor": {
                        "type": "object",
                        "properties": {
                            "rnc": {
                                "type": "string"
                            },
                            "razon_social": {
                                "type": "string"
                            }
                        }
                    },
                    "fecha_emision": {
                        "type": "string",
                        "format": "date"
                    },
                    "totales": {
                        "$ref": "#/components/schemas/Totales"
                    },
                    "aprobacion": {
                        "type": "string",
                        "enum": [
                            "pendiente",
                            "aprobado",
                            "rechazado"
                        ]
                    },
                    "motivo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "recibido": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Cliente": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Comprador"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "creado": {
                                "type": "string",
                                "format": "date-time"
                            }
                        }
                    }
                ]
            },
            "Secuencia": {
                "type": "object",
                "properties": {
                    "tipo": {
                        "type": "integer"
                    },
                    "desde": {
                        "type": "integer"
                    },
                    "hasta": {
                        "type": "integer"
                    },
                    "siguiente": {
                        "type": "integer"
                    },
                    "disponibles": {
                        "type": "integer"
                    },
                    "vence": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "activa": {
                        "type": "boolean"
                    }
                }
            },
            "Contribuyente": {
                "type": "object",
                "properties": {
                    "rnc": {
                        "type": "string"
                    },
                    "razon_social": {
                        "type": "string"
                    },
                    "nombre_comercial": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "estado": {
                        "type": "string"
                    },
                    "emisor_electronico": {
                        "type": "boolean"
                    }
                }
            },
            "Evento": {
                "type": "object",
                "required": [
                    "id",
                    "evento",
                    "creado",
                    "datos"
                ],
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "evento": {
                        "type": "string"
                    },
                    "creado": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "datos": {
                        "type": "object"
                    }
                }
            }
        }
    }
}
