{
  "openapi": "3.0.3",
  "info": {
    "title": "AIONVEX - Facturacion para sistemas externos",
    "version": "1.0.0",
    "description": "Facturacion para sistemas externos. Empresa configurada desde el panel; API limitada a boletas y facturas."
  },
  "servers": [
    {
      "url": "https://api.aionvex.com/v1",
      "description": "API publica AIONVEX"
    }
  ],
  "security": [
    {
      "ApiKey": [],
      "ApiSecret": []
    }
  ],
  "paths": {
    "/boletas": {
      "post": {
        "summary": "Emitir boleta",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
            },
            "description": "Referencia unica de la venta, conservar en cada reintento."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Boleta"
              },
              "example": {
                "serie": "B001",
                "fecha_emision": "2026-10-08",
                "tipo_moneda": "PEN",
                "forma_pago": "Contado",
                "cliente": {
                  "tipo_doc": "1",
                  "num_doc": "00000001",
                  "razon_social": "CLIENTE DE EJEMPLO"
                },
                "items": [
                  {
                    "codigo": "P001",
                    "descripcion": "Producto de ejemplo",
                    "unidad": "NIU",
                    "cantidad": 1,
                    "precio_unitario": 118.0,
                    "tip_afe_igv": "10",
                    "porcentaje_igv": 18
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creado o respuesta idempotente de la emision original"
          },
          "400": {
            "description": "JSON no valido"
          },
          "401": {
            "description": "Credenciales invalidas o negocio inactivo"
          },
          "403": {
            "description": "Documento no habilitado"
          },
          "409": {
            "description": "Referencia en proceso, en revision, o usada con datos distintos"
          },
          "413": {
            "description": "Body mayor a 2 MB (2 000 000 bytes)"
          },
          "415": {
            "description": "Content-Type no soportado"
          },
          "422": {
            "description": "Error de validacion. Las comprobaciones locales detienen el envio y agrupan todos los errores detectados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorValidacion"
                },
                "example": {
                  "estado": "error",
                  "mensaje": "Error de validación",
                  "errores": {
                    "cliente.num_doc": [
                      "El RUC debe contener exactamente 11 digitos."
                    ],
                    "items.0.cantidad": [
                      "La cantidad debe ser un numero mayor que cero."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Configuracion o respuesta upstream no confirmada"
          }
        }
      }
    },
    "/boletas/{id}": {
      "get": {
        "summary": "Consultar boleta",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    },
    "/boletas/{id}/pdf": {
      "get": {
        "summary": "Descargar PDF",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "a4",
                "a5",
                "ticket-80",
                "ticket-58"
              ],
              "default": "a4"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          },
          "422": {
            "description": "Error de validacion. Las comprobaciones locales detienen el envio y agrupan todos los errores detectados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorValidacion"
                },
                "example": {
                  "estado": "error",
                  "mensaje": "Error de validación",
                  "errores": {
                    "cliente.num_doc": [
                      "El RUC debe contener exactamente 11 digitos."
                    ],
                    "items.0.cantidad": [
                      "La cantidad debe ser un numero mayor que cero."
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/boletas/{id}/xml": {
      "get": {
        "summary": "Descargar XML",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    },
    "/boletas/{id}/cdr": {
      "get": {
        "summary": "Descargar CDR",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    },
    "/facturas": {
      "post": {
        "summary": "Emitir factura",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
            },
            "description": "Referencia unica de la venta, conservar en cada reintento."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Factura"
              },
              "example": {
                "serie": "F001",
                "fecha_emision": "2026-10-08",
                "tipo_moneda": "PEN",
                "forma_pago": "Contado",
                "cliente": {
                  "tipo_doc": "6",
                  "num_doc": "20000000001",
                  "razon_social": "CLIENTE DE EJEMPLO"
                },
                "items": [
                  {
                    "codigo": "P001",
                    "descripcion": "Producto de ejemplo",
                    "unidad": "NIU",
                    "cantidad": 1,
                    "precio_unitario": 118.0,
                    "tip_afe_igv": "10",
                    "porcentaje_igv": 18
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creado o respuesta idempotente de la emision original"
          },
          "400": {
            "description": "JSON no valido"
          },
          "401": {
            "description": "Credenciales invalidas o negocio inactivo"
          },
          "403": {
            "description": "Documento no habilitado"
          },
          "409": {
            "description": "Referencia en proceso, en revision, o usada con datos distintos"
          },
          "413": {
            "description": "Body mayor a 2 MB (2 000 000 bytes)"
          },
          "415": {
            "description": "Content-Type no soportado"
          },
          "422": {
            "description": "Error de validacion. Las comprobaciones locales detienen el envio y agrupan todos los errores detectados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorValidacion"
                },
                "example": {
                  "estado": "error",
                  "mensaje": "Error de validación",
                  "errores": {
                    "cliente.num_doc": [
                      "El RUC debe contener exactamente 11 digitos."
                    ],
                    "items.0.cantidad": [
                      "La cantidad debe ser un numero mayor que cero."
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Configuracion o respuesta upstream no confirmada"
          }
        }
      }
    },
    "/facturas/{id}": {
      "get": {
        "summary": "Consultar factura",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    },
    "/facturas/{id}/pdf": {
      "get": {
        "summary": "Descargar PDF",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "a4",
                "a5",
                "ticket-80",
                "ticket-58"
              ],
              "default": "a4"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          },
          "422": {
            "description": "Error de validacion. Las comprobaciones locales detienen el envio y agrupan todos los errores detectados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorValidacion"
                },
                "example": {
                  "estado": "error",
                  "mensaje": "Error de validación",
                  "errores": {
                    "cliente.num_doc": [
                      "El RUC debe contener exactamente 11 digitos."
                    ],
                    "items.0.cantidad": [
                      "La cantidad debe ser un numero mayor que cero."
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/facturas/{id}/xml": {
      "get": {
        "summary": "Descargar XML",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    },
    "/facturas/{id}/cdr": {
      "get": {
        "summary": "Descargar CDR",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento o archivo del negocio autenticado"
          },
          "401": {
            "description": "Credenciales invalidas"
          },
          "404": {
            "description": "Documento ajeno/no registrado o archivo aun no disponible"
          },
          "429": {
            "description": "Limite por minuto"
          },
          "503": {
            "description": "Consulta no disponible"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "ApiSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Secret"
      }
    },
    "schemas": {
      "Cliente": {
        "type": "object",
        "required": [
          "tipo_doc",
          "num_doc",
          "razon_social"
        ],
        "properties": {
          "tipo_doc": {
            "type": "string",
            "description": "Factura: 6 (RUC). Boleta: 0,1,4,6,7, sujeto a validacion del comprobante."
          },
          "num_doc": {
            "type": "string",
            "description": "RUC de 11 digitos (10/20); DNI de 8. Conservar como texto."
          },
          "razon_social": {
            "type": "string",
            "maxLength": 1500
          },
          "direccion": {
            "type": "string",
            "maxLength": 500
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "telefono": {
            "type": "string",
            "maxLength": 20
          }
        }
      },
      "Item": {
        "type": "object",
        "required": [
          "descripcion",
          "unidad",
          "cantidad",
          "precio_unitario"
        ],
        "properties": {
          "codigo": {
            "type": "string",
            "maxLength": 30
          },
          "descripcion": {
            "type": "string",
            "maxLength": 500
          },
          "unidad": {
            "type": "string",
            "example": "NIU"
          },
          "cantidad": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
          },
          "precio_unitario": {
            "type": "number",
            "minimum": 0
          },
          "tip_afe_igv": {
            "type": "string",
            "example": "10"
          },
          "porcentaje_igv": {
            "type": "number",
            "example": 18
          },
          "mto_valor_unitario": {
            "type": "number",
            "minimum": 0
          }
        }
      },
      "Boleta": {
        "type": "object",
        "required": [
          "serie",
          "fecha_emision",
          "cliente",
          "items"
        ],
        "properties": {
          "serie": {
            "type": "string",
            "pattern": "^B[A-Z0-9]{3}$"
          },
          "correlativo": {
            "type": "integer",
            "minimum": 1,
            "description": "Opcional. Si se omite, se asigna por serie."
          },
          "fecha_emision": {
            "type": "string",
            "format": "date"
          },
          "fecha_vencimiento": {
            "type": "string",
            "format": "date"
          },
          "tipo_moneda": {
            "type": "string",
            "enum": [
              "PEN",
              "USD",
              "EUR"
            ]
          },
          "forma_pago": {
            "type": "string",
            "enum": [
              "Contado",
              "Credito"
            ]
          },
          "cliente": {
            "$ref": "#/components/schemas/Cliente"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "observacion": {
            "type": "string",
            "maxLength": 500
          },
          "cuotas": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "monto",
                "fecha_pago"
              ],
              "properties": {
                "monto": {
                  "type": "number",
                  "minimum": 0,
                  "exclusiveMinimum": true
                },
                "fecha_pago": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          }
        },
        "description": "Esquema resumido. Ver campos adicionales admitidos en /docs. No enviar configuracion de empresa."
      },
      "Factura": {
        "type": "object",
        "required": [
          "serie",
          "fecha_emision",
          "cliente",
          "items"
        ],
        "properties": {
          "serie": {
            "type": "string",
            "pattern": "^F[A-Z0-9]{3}$"
          },
          "correlativo": {
            "type": "integer",
            "minimum": 1,
            "description": "Opcional. Si se omite, se asigna por serie."
          },
          "fecha_emision": {
            "type": "string",
            "format": "date"
          },
          "fecha_vencimiento": {
            "type": "string",
            "format": "date"
          },
          "tipo_moneda": {
            "type": "string",
            "enum": [
              "PEN",
              "USD",
              "EUR"
            ]
          },
          "forma_pago": {
            "type": "string",
            "enum": [
              "Contado",
              "Credito"
            ]
          },
          "cliente": {
            "$ref": "#/components/schemas/Cliente"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "observacion": {
            "type": "string",
            "maxLength": 500
          },
          "cuotas": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "monto",
                "fecha_pago"
              ],
              "properties": {
                "monto": {
                  "type": "number",
                  "minimum": 0,
                  "exclusiveMinimum": true
                },
                "fecha_pago": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          }
        },
        "description": "Esquema resumido. Ver campos adicionales admitidos en /docs. No enviar configuracion de empresa."
      },
      "ErrorValidacion": {
        "type": "object",
        "required": [
          "estado",
          "mensaje",
          "errores"
        ],
        "properties": {
          "estado": {
            "type": "string",
            "enum": [
              "error"
            ]
          },
          "mensaje": {
            "type": "string",
            "example": "Error de validación"
          },
          "errores": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Campo del JSON (ej. cliente.num_doc, items.0.cantidad) o header/query (Idempotency-Key, format), asociado a una lista de mensajes. _general si no se identifica un campo."
          }
        }
      }
    }
  }
}