{
  "openapi": "3.1.0",
  "info": {
    "title": "Facturear API",
    "description": "API para emitir facturas electrónicas de ARCA (Argentina) desde tu sistema: facturas, notas de crédito y débito, lotes, PDF y XML, envío por email, borradores desde documentos, webhooks y reportes. Autenticación con API Key en el header x-api-key: la key de testing opera en homologación y la de producción emite comprobantes reales.",
    "version": "1.0.0",
    "contact": {
      "name": "Facturear Support",
      "email": "support@facture.ar",
      "url": "https://facture.ar"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "https://www.facture.ar/api",
      "description": "Servidor de producción"
    }
  ],
  "tags": [
    {
      "name": "CUITs",
      "description": "CUITs emisores, sus defaults, puntos de venta y diseño"
    },
    {
      "name": "Facturas",
      "description": "Emitir, listar y consultar facturas, su PDF y XML, y enviarlas por email"
    },
    {
      "name": "Lotes",
      "description": "El resultado de cada emisión: toda factura se procesa en un lote"
    },
    {
      "name": "Borradores",
      "description": "Facturas propuestas desde documentos, planillas o datos, para revisar y emitir"
    },
    {
      "name": "Plantillas",
      "description": "Cómo se lee y se factura cada tipo de documento, y facturas recurrentes"
    },
    {
      "name": "Importar desde ARCA",
      "description": "Traer a Facturear los comprobantes que ARCA ya autorizó"
    },
    {
      "name": "Webhooks",
      "description": "Notificaciones a tu sistema cuando pasa algo con tus facturas"
    },
    {
      "name": "Reportes",
      "description": "Libro IVA Ventas"
    },
    {
      "name": "Utilidades",
      "description": "Parámetros de ARCA"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/cuits": {
      "get": {
        "summary": "Obtener CUITs",
        "description": "Obtiene la lista de CUITs asociados a tu cuenta, con sus valores por defecto (default_pos, default_invoice_type, default_concept, default_iva, is_default).",
        "tags": ["CUITs"],
        "responses": {
          "200": {
            "description": "Lista de CUITs obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Cuit"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No autorizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Agregar un CUIT",
        "description": "Registra un CUIT en tu cuenta.",
        "tags": ["CUITs"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["number"],
                "properties": {
                  "number": {
                    "type": "string",
                    "description": "Número de CUIT"
                  },
                  "integrationMode": {
                    "type": "string",
                    "description": "Modo de conexión con ARCA"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "CUIT creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Cuit"
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Límite de CUITs del plan alcanzado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "El CUIT ya está registrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}": {
      "get": {
        "summary": "Obtener un CUIT",
        "description": "Devuelve un CUIT de tu cuenta con sus datos del padrón, puntos de venta, defaults y estado de la configuración en ARCA.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CUIT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Cuit"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/set-default": {
      "post": {
        "summary": "Marcar como CUIT por defecto",
        "description": "Marca este CUIT como el default de tu cuenta y desmarca los demás.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear o su número sin guiones",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "CUIT marcado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/setup-status": {
      "get": {
        "summary": "Estado de la configuración en ARCA",
        "description": "En qué paso está la configuración del CUIT en ARCA.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "setupStatus": {
                      "type": "string",
                      "enum": ["INITIALIZED", "IN_PROGRESS", "TEST_CERTIFICATE_COMPLETE", "PROD_CERTIFICATE_COMPLETE", "AWAITING_DELEGATION", "DELEGATION_COMPLETE", "AUTOMATION_IN_PROGRESS", "AUTOMATION_FAILED", "COMPLETED", "SKIPPED"]
                    },
                    "progress": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100,
                      "description": "Porcentaje: certificados, puntos de venta y concepto por defecto"
                    },
                    "isCompleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/pos": {
      "get": {
        "summary": "Listar puntos de venta",
        "description": "Los puntos de venta del CUIT guardados en Facturear (la última consulta a ARCA) y la última factura emitida desde Facturear en cada uno.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Puntos de venta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PointsOfSale"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Actualizar puntos de venta desde ARCA",
        "description": "Consulta en ARCA (producción) los puntos de venta del CUIT y los guarda. Tarda unos segundos.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Puntos de venta actualizados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "pos": {
                      "description": "Respuesta de ARCA a FEParamGetPtosVenta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "El CUIT no tiene puntos de venta dados de alta en ARCA",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "No se pudo consultar ARCA (por ejemplo, el CUIT no tiene certificados)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/pos/last-vouchers": {
      "get": {
        "summary": "Último comprobante por punto de venta",
        "description": "Consulta en ARCA el último comprobante autorizado en cada punto de venta activo del CUIT, lo haya emitido Facturear u otro sistema. Usa el entorno de la API key y tarda unos segundos.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Últimos comprobantes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "lastVouchers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LastVoucher"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "No se pudo consultar ARCA",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/default-pos": {
      "post": {
        "summary": "Configurar punto de venta por defecto",
        "description": "Configura el punto de venta que se usa cuando una factura no trae ptoVta.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["defaultPos"],
                "properties": {
                  "defaultPos": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Valor por defecto actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/default-invoice-type": {
      "post": {
        "summary": "Configurar tipo de comprobante por defecto",
        "description": "Configura el tipo de comprobante (código de ARCA) que se usa cuando una factura no trae invoiceType.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["defaultInvoiceType"],
                "properties": {
                  "defaultInvoiceType": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Valor por defecto actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/default-concept": {
      "post": {
        "summary": "Configurar concepto por defecto",
        "description": "Configura el concepto (1 productos, 2 servicios, 3 ambos) que se usa cuando una factura no trae concepto.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["defaultConcept"],
                "properties": {
                  "defaultConcept": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Valor por defecto actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/default-iva": {
      "post": {
        "summary": "Configurar alícuota de IVA por defecto",
        "description": "Configura la alícuota de IVA (código de ARCA) preseleccionada en los formularios del dashboard.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["defaultIva"],
                "properties": {
                  "defaultIva": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Valor por defecto actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "CUIT actualizado"
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/cuits/{cuitId}/invoice-branding": {
      "get": {
        "summary": "Obtener el diseño de factura",
        "description": "Plantilla, logo, color y datos del emisor con que se imprimen las facturas del CUIT.",
        "tags": ["CUITs"],
        "parameters": [{ "name": "cuitId", "in": "path", "description": "ID del CUIT en Facturear", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Diseño de factura", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceBranding" } } } },
          "404": { "description": "CUIT no encontrado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      },
      "put": {
        "summary": "Cambiar el diseño de factura",
        "description": "Cambia los campos enviados; los que no se envían quedan como están y null borra un valor. Se aplica también al PDF de las facturas ya emitidas.",
        "tags": ["CUITs"],
        "parameters": [{ "name": "cuitId", "in": "path", "description": "ID del CUIT en Facturear", "required": true, "schema": { "type": "string" } }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceBranding" } } } },
        "responses": {
          "200": { "description": "Diseño actualizado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceBranding" } } } },
          "400": { "description": "Valor inválido", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": { "description": "CUIT no encontrado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/cuits/{cuitId}/email-design": {
      "get": {
        "summary": "Obtener el diseño del mail",
        "description": "El diseño del mail con el que sale la factura de este CUIT. Los campos en null usan el valor por defecto.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Diseño del mail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailDesign"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Cambiar el diseño del mail",
        "description": "Los campos que no mandás quedan como están; null (o texto vacío) vuelve al valor por defecto. En signature, el texto vacío deja el mail sin firma.",
        "tags": ["CUITs"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "path",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailDesign"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Diseño guardado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailDesign"
                }
              }
            }
          },
          "400": {
            "description": "Valor inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{invoiceId}/email": {
      "post": {
        "summary": "Enviar la factura por email",
        "description": "Envía el PDF de una factura autorizada desde noreply@facture.ar (solo envío, no recibe respuestas). Hasta 5 destinatarios por envío. Por mes podés mandar tantas facturas distintas como facturas emite tu plan (reenviar una que ya mandaste ese mes no suma), y cada factura hasta 5 veces cada 24 horas.",
        "tags": ["Facturas"],
        "parameters": [{ "name": "invoiceId", "in": "path", "description": "ID de la factura", "required": true, "schema": { "type": "string" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["to"],
                "properties": {
                  "to": { "oneOf": [{ "type": "array", "items": { "type": "string", "format": "email" }, "minItems": 1, "maxItems": 5 }, { "type": "string", "description": "Direcciones separadas por coma" }] },
                  "message": { "type": "string", "maxLength": 2000, "description": "Mensaje opcional para el cliente" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Enviada", "content": { "application/json": { "schema": { "type": "object", "properties": { "sent": { "type": "boolean" }, "to": { "type": "array", "items": { "type": "string" } } } } } } },
          "400": { "description": "Destinatarios inválidos o factura no autorizada", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": { "description": "Factura no encontrada", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "La factura ya se mandó 5 veces en las últimas 24 horas, o llegaste al límite mensual de facturas enviadas de tu plan", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/invoices/{invoiceId}/credit-note": {
      "post": {
        "summary": "Anular una factura con nota de crédito",
        "description": "Encola la nota de crédito que anula por el total una factura A, B, C o M autorizada por ARCA (A→NC A, B→NC B, C→NC C, M→NC M): mismo receptor, ítems, importes y moneda, asociada a la factura (`CbtesAsoc`) y con fecha de hoy. No cuenta contra el límite de facturas del plan. Es asíncrono: seguí el `batchId` con `GET /invoices/batches/{batchId}`. Una factura se anula una sola vez: mientras su nota está en la cola, en ARCA o ya autorizada, otro pedido responde `409`. Mandá un header `Idempotency-Key` para poder reintentar sin pedir dos veces (ver la guía de idempotencia).",
        "tags": [
          "Facturas"
        ],
        "parameters": [
          {
            "name": "invoiceId",
            "in": "path",
            "description": "ID de la factura a anular",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "Nota de crédito encolada. Un reenvío con el mismo `Idempotency-Key` devuelve esta misma respuesta.",
            "headers": {
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "batchId": {
                      "type": "string",
                      "description": "Lote a seguir con GET /invoices/batches/{batchId}"
                    },
                    "voids": {
                      "type": "string",
                      "description": "La factura que se anula",
                      "example": "Factura C 0003-00000012"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "La factura no se puede anular: no está autorizada por ARCA, no es A, B, C o M, o ya es una nota de crédito de anulación. También si el `Idempotency-Key` es inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "API key faltante o inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Factura no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "La factura ya fue anulada (`creditNoteId`), su nota de crédito está en la cola o en ARCA (`batchId` para seguirla), o hay una solicitud en curso con este `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "creditNoteId": {
                      "type": "string",
                      "description": "ID de la nota de crédito que ya anuló la factura"
                    },
                    "batchId": {
                      "type": "string",
                      "description": "Lote de la nota de crédito que está en curso"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/IdempotencyKeyReused"
          }
        }
      }
    },
    "/invoices": {
      "get": {
        "summary": "Listar facturas",
        "description": "Lista las facturas del entorno de la API key, de la más nueva a la más vieja, con filtros y paginación.",
        "tags": ["Facturas"],
        "parameters": [
          {
            "name": "cuit",
            "in": "query",
            "description": "CUIT emisor (o parte de él)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cuitId",
            "in": "query",
            "description": "ID del CUIT emisor en Facturear (filtro exacto). Alternativa a cuit",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tipo",
            "in": "query",
            "description": "Código de ARCA del tipo de comprobante",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "comprobante",
            "in": "query",
            "description": "Número de comprobante",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "receptor",
            "in": "query",
            "description": "Documento del receptor (CUIT, CUIL o DNI, con o sin guiones: busca por DocNro exacto) o parte de su nombre (clientName, sin distinguir mayúsculas)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Estado de la factura",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["success", "error", "processing"]
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Busca en CUIT emisor, número de comprobante, código de tipo de comprobante y descripción",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Número de página",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Elementos por página",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Facturas obtenidas exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoices": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Crear facturas",
        "description": "Crea facturas electrónicas individuales o en lote. El sistema procesa las solicitudes de forma asíncrona a través de un sistema de colas. Mandá un header `Idempotency-Key` para poder reintentar sin duplicar facturas (ver la guía de idempotencia).",
        "tags": ["Facturas"],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/InvoiceRequest"
                  },
                  {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/InvoiceRequest"
                    },
                    "maxItems": 500
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Factura(s) aceptada(s) para procesamiento",
            "headers": { "Idempotent-Replayed": { "$ref": "#/components/headers/IdempotentReplayed" } },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Datos de factura inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Límite de facturas del plan alcanzado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": { "$ref": "#/components/responses/IdempotencyInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReused" }
        }
      }
    },
    "/invoices/{invoiceId}": {
      "get": {
        "summary": "Obtener factura por ID",
        "description": "Obtiene los detalles de una factura específica por su ID.",
        "tags": ["Facturas"],
        "parameters": [
          {
            "name": "invoiceId",
            "in": "path",
            "description": "ID de la factura",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Factura obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "404": {
            "description": "Factura no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/stats": {
      "get": {
        "summary": "Resumen de facturas",
        "description": "Totales de las facturas del entorno de la API key.",
        "tags": ["Facturas"],
        "responses": {
          "200": {
            "description": "Resumen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalAmount": {
                      "type": "number",
                      "description": "Suma de las facturas exitosas"
                    },
                    "totalInvoices": {
                      "type": "integer"
                    },
                    "successInvoices": {
                      "type": "integer"
                    },
                    "errorInvoices": {
                      "type": "integer"
                    },
                    "pendingJobs": {
                      "type": "integer",
                      "description": "Facturas en cola"
                    },
                    "environment": {
                      "type": "string",
                      "enum": ["production", "homologation"],
                      "description": "Entorno del que salen los números"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/arca/{name}": {
      "get": {
        "summary": "Obtener parámetro ARCA específico",
        "description": "Obtiene un parámetro específico de AFIP/ARCA por nombre. Estos parámetros son esenciales para la facturación electrónica en Argentina.",
        "tags": ["Utilidades"],
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "Nombre del parámetro AFIP a obtener",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "FEPARAMGETTIPOSDOC",
                "FEPARAMGETTIPOSCBTE",
                "FEPARAMGETTIPOSCONCEPTO",
                "FEPARAMGETTIPOSIVA",
                "FEPARAMGETTIPOSMONEDAS",
                "FEPARAMGETTIPOSTRIBUTOS",
                "FEPARAMGETCOTIZACION",
                "FEPARAMGETCONDICIONIVARECEPTOR"
              ]
            }
          },
          {
            "name": "codId",
            "in": "query",
            "description": "ID de moneda de ARCA, por ejemplo DOL (requerido para FEPARAMGETCOTIZACION)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "claseCmp",
            "in": "query",
            "description": "Clase de comprobante (A, B, C, M) para filtrar FEPARAMGETCONDICIONIVARECEPTOR",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Parámetro ARCA obtenido exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Respuesta de ARCA tal cual. La lista viene dentro de ResultGet (por ejemplo ResultGet.IvaTipo o ResultGet.CbteTipo)",
                  "properties": {
                    "ResultGet": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parámetro inválido o faltante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ARCA no disponible",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/batches": {
      "get": {
        "summary": "Listar lotes de facturas",
        "description": "Obtiene la lista de lotes de facturas con paginación.",
        "tags": ["Lotes"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Número de página",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Elementos por página",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de lotes obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "batches": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Batch"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/invoices/batches/{batchId}": {
      "get": {
        "summary": "Obtener lote por ID",
        "description": "Obtiene los detalles completos de un lote específico, incluyendo todos sus items.",
        "tags": ["Lotes"],
        "parameters": [
          {
            "name": "batchId",
            "in": "path",
            "description": "ID del lote",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lote obtenido exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchDetail"
                }
              }
            }
          },
          "404": {
            "description": "Lote no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Agregar facturas a lote",
        "description": "Agrega facturas adicionales a un lote existente que aún no ha sido completado. Con `Idempotency-Key`, reenviar el mismo agregado no suma las facturas dos veces, aunque el lote ya haya terminado.",
        "tags": ["Lotes"],
        "parameters": [
          {
            "name": "batchId",
            "in": "path",
            "description": "ID del lote",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "minItems": 1,
                "maxItems": 500,
                "items": {
                  "$ref": "#/components/schemas/InvoiceRequest"
                },
                "description": "Facturas a agregar al lote"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Facturas agregadas al lote exitosamente",
            "headers": { "Idempotent-Replayed": { "$ref": "#/components/headers/IdempotentReplayed" } },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "batch": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer",
                      "description": "Cantidad de facturas agregadas"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["processing"]
                    },
                    "batchId": {
                      "type": "string"
                    },
                    "addedToExistingBatch": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos o lote ya completado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": { "$ref": "#/components/responses/IdempotencyInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReused" }
        }
      }
    },
    "/invoices/batches/{batchId}/items/{itemId}/retry": {
      "post": {
        "summary": "Reintentar item de lote",
        "description": "Reintenta el procesamiento de un item específico que falló en un lote. Solo items en estado error, hasta 5 reintentos manuales por item.",
        "tags": ["Lotes"],
        "parameters": [
          {
            "name": "batchId",
            "in": "path",
            "description": "ID del lote",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemId",
            "in": "path",
            "description": "ID del item del lote",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Item reintentado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string",
                      "description": "Mensaje de confirmación"
                    },
                    "itemId": {
                      "type": "string",
                      "description": "ID del item"
                    },
                    "newStatus": {
                      "type": "string",
                      "enum": ["pending"],
                      "description": "Nuevo estado del item"
                    },
                    "manualRetryCount": {
                      "type": "integer",
                      "description": "Reintentos manuales hechos (máximo 5)"
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "El item no está en estado error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "404": {
            "description": "Lote o item no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": { "description": "El item cambió de estado mientras se reintentaba (por ejemplo, otro reintento simultáneo ya lo volvió a encolar)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "El item ya tuvo 5 reintentos manuales. Contactá soporte", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/invoices/{invoiceId}/pdf": {
      "get": {
        "summary": "Obtener PDF de factura",
        "description": "Genera el PDF de una factura. Por defecto devuelve una URL de descarga; con download=true devuelve el archivo. Si el pedido acepta text/html (un navegador que abre el link), responde 302 directo al PDF.",
        "tags": ["Facturas"],
        "parameters": [
          {
            "name": "invoiceId",
            "in": "path",
            "description": "ID de la factura",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "download",
            "in": "query",
            "description": "true para recibir el PDF en lugar de la URL",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "URL de descarga del PDF, o el PDF si download=true",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "download_url": {
                      "type": "string"
                    },
                    "invoice_id": {
                      "type": "string"
                    },
                    "invoice_number": {
                      "type": "string",
                      "description": "Punto de venta y número, por ejemplo 0001-00000145"
                    },
                    "environment": {
                      "type": "string"
                    }
                  }
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "Factura no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{invoiceId}/xml": {
      "get": {
        "summary": "Obtener el XML de la factura",
        "description": "La respuesta de ARCA (FECAESolicitarResponse) de una factura autorizada, como sobre SOAP en XML.",
        "tags": ["Facturas"],
        "parameters": [
          {
            "name": "invoiceId",
            "in": "path",
            "description": "ID de la factura",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "XML de la respuesta de ARCA",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "La factura no existe o no tiene respuesta de ARCA",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "summary": "Listar webhooks",
        "description": "Los webhooks de tu cuenta. El secreto de firma no se devuelve: se ve desde el dashboard.",
        "tags": ["Webhooks"],
        "responses": {
          "200": {
            "description": "Webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Webhook"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Crear un webhook",
        "description": "Registra una URL que recibe los eventos elegidos. Facturear genera el secreto de firma (whsec_...), que se ve desde el dashboard en Webhooks → Secreto de firma.",
        "tags": ["Webhooks"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEvent"
                    }
                  },
                  "headers": {
                    "type": ["object", "null"],
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": ["url", "events"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "URL o eventos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{webhookId}": {
      "put": {
        "summary": "Editar un webhook",
        "description": "Cambia la URL, los eventos, los headers o lo pausa (isActive: false). Solo se cambian los campos que mandás.",
        "tags": ["Webhooks"],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "description": "ID del webhook",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEvent"
                    }
                  },
                  "headers": {
                    "type": ["object", "null"],
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "isActive": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Webhook no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Borrar un webhook",
        "tags": ["Webhooks"],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "description": "ID del webhook",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook borrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Webhook no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/reports/libro-iva": {
      "get": {
        "summary": "Libro IVA Ventas (CSV)",
        "description": "Los comprobantes autorizados del período, en CSV separado por punto y coma (para Excel en castellano). Columnas: Fecha, Tipo, Punto de venta, Número, CUIT emisor, Doc. receptor, Moneda, Neto gravado, IVA, Exento, No gravado, Otros tributos, Total. Las notas de crédito van en negativo. Usa el entorno de la API key.",
        "tags": ["Reportes"],
        "parameters": [
          {
            "name": "desde",
            "in": "query",
            "description": "Primer día, AAAA-MM-DD. Por defecto, el primero del mes",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "hasta",
            "in": "query",
            "description": "Último día, AAAA-MM-DD. Por defecto, hoy. El período se corta a 366 días",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "cuit",
            "in": "query",
            "description": "ID del CUIT en Facturear, para ver uno solo. Sin él, todos",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Archivo CSV",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/documents": {
      "post": {
        "summary": "Proponer facturas desde un documento",
        "description": "Arma borradores de factura a partir de un archivo (fileUrl, o multipart con el campo file), un texto (text) o los datos ya estructurados (data, uno o hasta 100). Los archivos y textos se leen con IA en segundo plano: los borradores vuelven con status extracting; consultalos con GET /documents/drafts. El entorno lo fija la API key. Las solicitudes JSON aceptan `Idempotency-Key`: un reenvío devuelve los mismos borradores en vez de crear otros (ni, en modo automático, emitir otra factura).",
        "tags": ["Borradores"],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "templateId": {
                    "type": ["string", "null"],
                    "description": "Plantilla que define CUIT, punto de venta, modo, cliente fijo, precios e instrucciones"
                  },
                  "mode": {
                    "type": "string",
                    "enum": ["manual", "automatic"],
                    "description": "automatic: se emite solo si no hay observaciones"
                  },
                  "cuitId": {
                    "type": ["string", "null"]
                  },
                  "ptoVta": {
                    "type": ["integer", "null"],
                    "minimum": 1
                  },
                  "dedupeKey": {
                    "type": ["string", "null"],
                    "maxLength": 200,
                    "description": "Id estable del documento: repetir el pedido con el mismo valor no duplica el borrador"
                  },
                  "sourceRef": {
                    "type": ["string", "null"],
                    "maxLength": 200,
                    "description": "Referencia que se muestra en el borrador"
                  },
                  "source": {
                    "type": "string",
                    "enum": ["api", "zapier", "mcp"],
                    "default": "api"
                  },
                  "fileUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL pública del archivo (PDF, imagen o planilla)"
                  },
                  "fileName": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "mimeType": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string",
                    "description": "Texto del documento (un pedido, un mensaje)"
                  },
                  "data": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/DraftData"
                      },
                      {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 100,
                        "items": {
                          "$ref": "#/components/schemas/DraftData"
                        }
                      }
                    ]
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Hasta 25 MB"
                  },
                  "templateId": {
                    "type": ["string", "null"],
                    "description": "Plantilla que define CUIT, punto de venta, modo, cliente fijo, precios e instrucciones"
                  },
                  "mode": {
                    "type": "string",
                    "enum": ["manual", "automatic"],
                    "description": "automatic: se emite solo si no hay observaciones"
                  },
                  "cuitId": {
                    "type": ["string", "null"]
                  },
                  "ptoVta": {
                    "type": ["integer", "null"],
                    "minimum": 1
                  },
                  "dedupeKey": {
                    "type": ["string", "null"],
                    "maxLength": 200,
                    "description": "Id estable del documento: repetir el pedido con el mismo valor no duplica el borrador"
                  },
                  "sourceRef": {
                    "type": ["string", "null"],
                    "maxLength": 200,
                    "description": "Referencia que se muestra en el borrador"
                  },
                  "source": {
                    "type": "string",
                    "enum": ["api", "zapier", "mcp"],
                    "default": "api"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Borradores creados",
            "headers": { "Idempotent-Replayed": { "$ref": "#/components/headers/IdempotentReplayed" } },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "drafts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Draft"
                      }
                    },
                    "mapping": {
                      "type": "object",
                      "description": "Solo planillas: las columnas usadas y si la IA las acaba de proponer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Falta el documento o los datos son inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": { "$ref": "#/components/responses/IdempotencyInProgress" },
          "422": { "$ref": "#/components/responses/IdempotencyKeyReused" }
        }
      }
    },
    "/documents/drafts": {
      "get": {
        "summary": "Listar borradores",
        "description": "Los borradores del entorno de la API key, los más nuevos primero.",
        "tags": ["Borradores"],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filtrar por estado. pending = leyéndose, para revisar, con error o en camino a ARCA",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["extracting", "review", "queued", "invoiced", "error", "discarded", "pending"]
            }
          },
          {
            "name": "source",
            "in": "query",
            "description": "Filtrar por origen",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["upload", "google_drive", "zapier", "api", "recurring", "mcp", "whatsapp"]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Cantidad máxima",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Borradores",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "drafts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Draft"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/documents/drafts/{draftId}": {
      "get": {
        "summary": "Obtener un borrador",
        "tags": ["Borradores"],
        "parameters": [
          {
            "name": "draftId",
            "in": "path",
            "description": "ID del borrador",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Borrador",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "draft": {
                      "$ref": "#/components/schemas/Draft"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "El borrador no existe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Corregir un borrador",
        "description": "Cambia los datos, el CUIT o el punto de venta de un borrador que espera revisión. Con una API key, environment solo se acepta si coincide con el de la key.",
        "tags": ["Borradores"],
        "parameters": [
          {
            "name": "draftId",
            "in": "path",
            "description": "ID del borrador",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "$ref": "#/components/schemas/DraftData"
                  },
                  "cuitId": {
                    "type": ["string", "null"]
                  },
                  "ptoVta": {
                    "type": ["integer", "null"],
                    "minimum": 1
                  },
                  "environment": {
                    "type": "string",
                    "enum": ["production", "homologation"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Borrador actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "draft": {
                      "$ref": "#/components/schemas/Draft"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos o el borrador ya no se puede editar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Descartar un borrador",
        "tags": ["Borradores"],
        "parameters": [
          {
            "name": "draftId",
            "in": "path",
            "description": "ID del borrador",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Borrador descartado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "discarded": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "El borrador no se puede descartar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/drafts/{draftId}/email": {
      "post": {
        "summary": "Enviar la factura de un borrador por email",
        "description": "Envía (o reenvía) la factura emitida desde el borrador a una dirección.",
        "tags": ["Borradores"],
        "parameters": [
          {
            "name": "draftId",
            "in": "path",
            "description": "ID del borrador",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado del envío",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": ["string", "null"],
                      "description": "Estado del envío"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Email inválido o el borrador todavía no tiene factura",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/drafts/invoice": {
      "post": {
        "summary": "Emitir borradores",
        "description": "Emite ante ARCA los borradores indicados. Con la key de producción son comprobantes reales. Con una API key solo se emiten los borradores de su entorno.",
        "tags": ["Borradores"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["ids"],
                "properties": {
                  "ids": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 500,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "integer",
                      "description": "Borradores enviados a ARCA"
                    },
                    "batchIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Lotes creados; consultalos en GET /invoices/batches/{batchId}"
                    },
                    "failed": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "draftId": {
                            "type": "string"
                          },
                          "error": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/drafts/discard": {
      "post": {
        "summary": "Descartar borradores",
        "tags": ["Borradores"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["ids"],
                "properties": {
                  "ids": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 500,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cantidad descartada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "discarded": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/templates": {
      "get": {
        "summary": "Listar plantillas",
        "tags": ["Plantillas"],
        "responses": {
          "200": {
            "description": "Plantillas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templates": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Template"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Crear una plantilla",
        "description": "Una plantilla define cómo se lee y se factura un tipo de documento (CUIT, punto de venta, modo, cliente fijo, precios, instrucciones para la IA, columnas de la planilla) y, con recurrence, una factura que sale sola todos los meses.",
        "tags": ["Plantillas"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plantilla creada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "template": {
                      "$ref": "#/components/schemas/Template"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/documents/templates/{templateId}": {
      "get": {
        "summary": "Obtener una plantilla",
        "tags": ["Plantillas"],
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "ID de la plantilla",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "template": {
                      "$ref": "#/components/schemas/Template"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "La plantilla no existe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Reemplazar una plantilla",
        "description": "Reemplaza la plantilla con el body completo: los campos que no mandás vuelven a su valor por defecto, salvo columnMapping, que se conserva si no lo mandás.",
        "tags": ["Plantillas"],
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "ID de la plantilla",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plantilla actualizada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "template": {
                      "$ref": "#/components/schemas/Template"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos o la plantilla no existe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Borrar una plantilla",
        "tags": ["Plantillas"],
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "ID de la plantilla",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla borrada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/documents/templates/{templateId}/run": {
      "post": {
        "summary": "Emitir ya la factura recurrente del mes",
        "description": "Genera ahora el borrador del mes de una plantilla recurrente. Como mucho una vez por mes.",
        "tags": ["Plantillas"],
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "description": "ID de la plantilla",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Borrador del mes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "draft": {
                      "$ref": "#/components/schemas/Draft"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "La plantilla no existe o no se puede emitir",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/arca-imports": {
      "get": {
        "summary": "Último relevamiento de un CUIT",
        "description": "El relevamiento más reciente del CUIT en el entorno de la API key, o null.",
        "tags": ["Importar desde ARCA"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "query",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Relevamiento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/ArcaImport"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Falta cuitId",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Relevar los comprobantes de ARCA",
        "description": "Empieza a relevar los comprobantes que ARCA ya autorizó para el CUIT en el período. Si ya hay un relevamiento en curso, lo devuelve. Cuando llega a status ready, importalo con la acción start.",
        "tags": ["Importar desde ARCA"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["cuitId", "range"],
                "properties": {
                  "cuitId": {
                    "type": "string"
                  },
                  "range": {
                    "type": "string",
                    "enum": ["mes", "anio", "anio-pasado"],
                    "description": "mes: desde principio de mes; anio: desde principio de año; anio-pasado: el año pasado"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Relevamiento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/ArcaImport"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Falta el CUIT o el período",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "La importación no está disponible en este momento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/arca-imports/{importId}": {
      "post": {
        "summary": "Avanzar un relevamiento",
        "description": "start: importa lo relevado (status ready); retry: reintenta uno con error; cancel: lo cancela; resume: lo retoma si quedó parado.",
        "tags": ["Importar desde ARCA"],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "description": "ID del relevamiento",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["action"],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": ["start", "retry", "cancel", "resume"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Relevamiento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/ArcaImport"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Acción desconocida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No se encontró la importación",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/arca-imports/vouchers": {
      "get": {
        "summary": "Comprobantes importados desde ARCA",
        "description": "Los comprobantes del CUIT importados desde ARCA (origin arca), los más recientes primero. Devuelve hasta 100 y el total.",
        "tags": ["Importar desde ARCA"],
        "parameters": [
          {
            "name": "cuitId",
            "in": "query",
            "description": "ID del CUIT en Facturear",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Comprobantes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vouchers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID de la factura en Facturear"
                          },
                          "issuedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "typeName": {
                            "type": "string"
                          },
                          "number": {
                            "type": "string",
                            "description": "Punto de venta y número, por ejemplo 0001-00000145"
                          },
                          "receiver": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "number"
                          },
                          "moneda": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Falta cuitId",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CUIT no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Cuit": {
        "type": "object",
        "description": "CUIT de tu cuenta. Nunca incluye certificados, claves privadas ni tickets de acceso.",
        "required": [
          "id",
          "number",
          "testing_certificate_valid",
          "production_certificate_valid",
          "testing_afip_connection_valid",
          "production_afip_connection_valid",
          "is_default",
          "setupStatus",
          "userId",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "cm1a2b3c4d5e6f7g8h9i0j",
            "description": "ID del CUIT"
          },
          "number": {
            "type": "string",
            "pattern": "^[0-9]{2}-[0-9]{8}-[0-9]{1}$",
            "example": "20-12345678-9",
            "description": "Número de CUIT en formato XX-XXXXXXXX-X"
          },
          "persona": {
            "type": ["object", "null"],
            "description": "Datos del padrón de ARCA (datosGenerales, datosMonotributo o datosRegimenGeneral, etc.) tal como los devuelve ARCA"
          },
          "personaLastUpdated": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Última actualización de los datos del padrón"
          },
          "pos": {
            "type": ["object", "null"],
            "description": "Puntos de venta tal como los devuelve ARCA (FEParamGetPtosVenta). La lista está en ResultGet.PtoVenta"
          },
          "posLastUpdated": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Última actualización de los puntos de venta"
          },
          "default_pos": {
            "type": ["integer", "null"],
            "description": "Punto de venta por defecto",
            "example": 1
          },
          "default_concept": {
            "type": ["integer", "null"],
            "description": "Concepto por defecto (1 productos, 2 servicios, 3 productos y servicios)",
            "example": 2
          },
          "default_invoice_type": {
            "type": ["integer", "null"],
            "description": "Tipo de comprobante por defecto (código de ARCA)",
            "example": 11
          },
          "default_iva": {
            "type": ["integer", "null"],
            "description": "Alícuota de IVA por defecto (código de ARCA)",
            "example": 5
          },
          "production_certificate_expiration": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Vencimiento del certificado de producción"
          },
          "production_ta_expiration": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Vencimiento del ticket de acceso de producción"
          },
          "testing_certificate_expiration": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Vencimiento del certificado de homologación"
          },
          "testing_ta_expiration": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Vencimiento del ticket de acceso de homologación"
          },
          "testing_certificate_valid": {
            "type": "boolean",
            "description": "El certificado de homologación es válido"
          },
          "production_certificate_valid": {
            "type": "boolean",
            "description": "El certificado de producción es válido"
          },
          "testing_afip_connection_valid": {
            "type": "boolean",
            "description": "La conexión con ARCA en homologación funciona"
          },
          "production_afip_connection_valid": {
            "type": "boolean",
            "description": "La conexión con ARCA en producción funciona"
          },
          "is_default": {
            "type": "boolean",
            "description": "Es el CUIT por defecto de la cuenta"
          },
          "setupStatus": {
            "type": "string",
            "enum": [
              "INITIALIZED",
              "IN_PROGRESS",
              "TEST_CERTIFICATE_COMPLETE",
              "PROD_CERTIFICATE_COMPLETE",
              "AWAITING_DELEGATION",
              "DELEGATION_COMPLETE",
              "AUTOMATION_IN_PROGRESS",
              "AUTOMATION_FAILED",
              "COMPLETED",
              "SKIPPED"
            ],
            "description": "Estado de la configuración del CUIT"
          },
          "integrationMode": {
            "type": ["string", "null"],
            "enum": ["DELEGATION", "CERTIFICATE", null],
            "description": "Modo de conexión con ARCA"
          },
          "testingSetupState": {
            "type": ["string", "null"],
            "enum": ["REQUESTED", "COMPLETED", null],
            "description": "Estado de la configuración de homologación. Solo viene en GET /cuits"
          },
          "productionSetupState": {
            "type": ["string", "null"],
            "enum": ["REQUESTED", "COMPLETED", null],
            "description": "Estado de la configuración de producción. Solo viene en GET /cuits"
          },
          "userId": {
            "type": "string",
            "description": "ID del usuario dueño del CUIT"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          }
        }
      },
      "InvoiceRequest": {
        "type": "object",
        "description": "Una factura. Todos los campos son opcionales salvo el importe: enviá impTotal (o amount, deprecado). Si no enviás cuitId ni cuit se usa el CUIT por defecto de la cuenta; lo que no envíes se completa con los valores por defecto del CUIT.",
        "properties": {
          "cuitId": {
            "type": "string",
            "description": "ID del CUIT emisor. Alternativa a cuit"
          },
          "cuit": {
            "type": "string",
            "example": "20-12345678-9",
            "description": "Número de CUIT emisor, con o sin guiones. Alternativa a cuitId"
          },
          "invoiceType": {
            "type": "integer",
            "description": "Tipo de comprobante (código de ARCA, por ejemplo 1 Factura A, 6 Factura B, 11 Factura C). Por defecto, el del CUIT; si no tiene, 11 para monotributistas y 6 para responsables inscriptos",
            "example": 11
          },
          "ptoVta": {
            "type": "integer",
            "description": "Punto de venta. Por defecto, el del CUIT (o 1)",
            "example": 1
          },
          "concepto": {
            "type": "integer",
            "enum": [1, 2, 3],
            "description": "Concepto: 1 productos, 2 servicios, 3 productos y servicios. Por defecto, el del CUIT (o 2 para monotributistas y 1 para el resto)"
          },
          "docTipo": {
            "type": "integer",
            "default": 99,
            "description": "Tipo de documento del receptor (código de ARCA: 80 CUIT, 86 CUIL, 96 DNI, 99 consumidor final)"
          },
          "docNro": {
            "type": "integer",
            "minimum": 0,
            "default": 0,
            "description": "Número de documento del receptor (0 para consumidor final)"
          },
          "condicionIVAReceptorId": {
            "type": "integer",
            "enum": [1, 4, 5, 6, 7, 8, 9, 10, 13, 15, 16],
            "description": "Condición frente al IVA del receptor (obligatoria para ARCA desde el 1/12/2026). Si no se envía: 5 (Consumidor Final) para receptores sin identificar o con DNI; para CUIT/CUIL se toma del padrón de ARCA, y si no se puede determinar la API responde 400. Debe corresponder a la clase del comprobante (A/M: 1, 6, 13, 16; B: 4, 5, 7, 8, 9, 10, 15; C: todas). Ver /es/guides/condicion-iva-receptor."
          },
          "monId": {
            "type": "string",
            "default": "PES",
            "description": "Moneda (código de ARCA, por ejemplo PES o DOL)"
          },
          "monCotiz": {
            "type": "number",
            "exclusiveMinimum": 0,
            "default": 1,
            "description": "Cotización de la moneda"
          },
          "description": {
            "type": "string",
            "default": "Venta de servicios",
            "description": "Descripción de la factura"
          },
          "clientName": {
            "type": "string",
            "maxLength": 200,
            "description": "Nombre o razón social del receptor, impreso en la factura. Si el receptor tiene CUIT y no se envía, se toma del padrón de ARCA"
          },
          "clientAddress": {
            "type": "string",
            "maxLength": 250,
            "description": "Domicilio del receptor, impreso en la factura"
          },
          "condicionVenta": {
            "type": "string",
            "enum": ["contado", "cuenta_corriente", "tarjeta_debito", "tarjeta_credito", "transferencia", "cheque", "otra"],
            "description": "Condición de venta impresa en la factura (RG 1415, Anexo II, B). ARCA no la recibe"
          },
          "emailTo": {
            "type": "array",
            "items": { "type": "string", "format": "email" },
            "minItems": 1,
            "maxItems": 5,
            "description": "Direcciones a las que se manda el PDF de la factura apenas ARCA la autoriza. Mismos límites que POST /invoices/{invoiceId}/email"
          },
          "fchServDesde": {
            "type": "string",
            "description": "Inicio del período facturado (servicios). Fecha en formato YYYYMMDD"
          },
          "fchServHasta": {
            "type": "string",
            "description": "Fin del período facturado (servicios). Fecha en formato YYYYMMDD"
          },
          "fchVtoPago": {
            "type": "string",
            "description": "Vencimiento del pago (servicios). Fecha en formato YYYYMMDD"
          },
          "cbteFch": {
            "type": "string",
            "pattern": "^[0-9]{8}$",
            "description": "Fecha del comprobante. Fecha en formato YYYYMMDD. Por defecto, hoy",
            "example": "20260928"
          },
          "impNeto": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 10000000,
            "description": "Importe neto gravado"
          },
          "impTotal": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 10000000,
            "description": "Importe total. Requerido si no enviás amount",
            "example": 1210
          },
          "impTotConc": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Importe neto no gravado"
          },
          "impOpEx": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Importe exento"
          },
          "impTrib": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Suma de los tributos"
          },
          "impIVA": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Suma del IVA"
          },
          "amount": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 10000000,
            "deprecated": true,
            "description": "Importe total. Deprecado: usá impTotal"
          },
          "cbtesAsoc": {
            "type": "array",
            "description": "Comprobantes asociados (notas de crédito y débito)",
            "items": {
              "type": "object",
              "required": ["tipo", "ptoVta", "nro"],
              "properties": {
                "tipo": {
                  "type": "integer",
                  "description": "Tipo de comprobante asociado"
                },
                "ptoVta": {
                  "type": "integer",
                  "description": "Punto de venta del comprobante asociado"
                },
                "nro": {
                  "type": "integer",
                  "description": "Número del comprobante asociado"
                },
                "cuit": {
                  "type": "string",
                  "description": "CUIT emisor del comprobante asociado"
                },
                "cbteFch": {
                  "type": "string",
                  "description": "Fecha del comprobante asociado. Fecha en formato YYYYMMDD"
                }
              }
            }
          },
          "tributos": {
            "type": "array",
            "description": "Tributos (percepciones, impuestos internos, etc.)",
            "items": {
              "type": "object",
              "required": ["id", "desc", "baseImp", "alic", "importe"],
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Código del tributo (FEPARAMGETTIPOSTRIBUTOS)"
                },
                "desc": {
                  "type": "string",
                  "description": "Descripción del tributo"
                },
                "baseImp": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Base imponible"
                },
                "alic": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100,
                  "description": "Alícuota en porcentaje"
                },
                "importe": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Importe del tributo"
                }
              }
            }
          },
          "iva": {
            "type": "array",
            "description": "Alícuotas de IVA",
            "items": {
              "type": "object",
              "required": ["id", "baseImp", "importe"],
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Código de la alícuota (FEPARAMGETTIPOSIVA, por ejemplo 5 = 21%)"
                },
                "baseImp": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Base imponible"
                },
                "importe": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Importe de IVA"
                }
              }
            }
          },
          "opcionales": {
            "type": "array",
            "description": "Datos opcionales de ARCA",
            "items": {
              "type": "object",
              "required": ["id", "valor"],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Código del opcional"
                },
                "valor": {
                  "type": "string",
                  "description": "Valor"
                }
              }
            }
          },
          "compradores": {
            "type": "array",
            "description": "Compradores (operaciones con varios compradores)",
            "items": {
              "type": "object",
              "required": ["docTipo", "docNro", "porcentaje"],
              "properties": {
                "docTipo": {
                  "type": "integer",
                  "description": "Tipo de documento del comprador"
                },
                "docNro": {
                  "type": "integer",
                  "description": "Número de documento del comprador"
                },
                "porcentaje": {
                  "type": "number",
                  "description": "Porcentaje de titularidad"
                }
              }
            }
          },
          "periodoAsoc": {
            "type": "object",
            "description": "Período asociado (notas de crédito y débito)",
            "required": ["fchDesde", "fchHasta"],
            "properties": {
              "fchDesde": {
                "type": "string",
                "description": "Desde. Fecha en formato YYYYMMDD"
              },
              "fchHasta": {
                "type": "string",
                "description": "Hasta. Fecha en formato YYYYMMDD"
              }
            }
          },
          "actividades": {
            "type": "array",
            "description": "Actividades del emisor",
            "items": {
              "type": "object",
              "required": ["id"],
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Código de actividad"
                }
              }
            }
          },
          "items": {
            "type": "array",
            "maxItems": 500,
            "description": "Ítems de la factura (se muestran en el PDF)",
            "items": {
              "type": "object",
              "required": ["description", "quantity", "unitPrice", "discount", "ivaRate", "subtotal"],
              "properties": {
                "description": {
                  "type": "string",
                  "description": "Descripción del ítem"
                },
                "quantity": {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "description": "Cantidad"
                },
                "unitPrice": {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "description": "Precio unitario"
                },
                "discount": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100,
                  "description": "Descuento en porcentaje"
                },
                "ivaRate": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100,
                  "description": "Alícuota de IVA en porcentaje"
                },
                "subtotal": {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "description": "Subtotal del ítem"
                }
              }
            }
          }
        }
      },
      "Invoice": {
        "type": "object",
        "required": [
          "id",
          "userId",
          "cuitId",
          "environment",
          "amount",
          "voucherNumber",
          "feCAEReq",
          "status",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de la factura"
          },
          "userId": {
            "type": "string",
            "description": "ID del usuario"
          },
          "cuitId": {
            "type": "string",
            "description": "ID del CUIT emisor"
          },
          "environment": {
            "type": "string",
            "enum": ["production", "homologation"],
            "description": "Entorno en el que se emitió"
          },
          "amount": {
            "type": "number",
            "example": 1210,
            "description": "Importe total"
          },
          "voucherNumber": {
            "type": "integer",
            "example": 145,
            "description": "Número de comprobante"
          },
          "ptoVta": {
            "type": ["integer", "null"],
            "description": "Punto de venta",
            "example": 1
          },
          "invoiceType": {
            "type": ["integer", "null"],
            "description": "Tipo de comprobante (código de ARCA)",
            "example": 11
          },
          "feCAEReq": {
            "type": "object",
            "description": "Solicitud enviada a ARCA (FeCAEReq con FeCabReq y FeDetReq), más items, tributos y clientName"
          },
          "feCabResp": {
            "type": ["object", "null"],
            "description": "Respuesta de ARCA tal cual (FeCabResp y FeDetResp; el CAE y su vencimiento están en FeDetResp.FECAEDetResponse)"
          },
          "status": {
            "type": "string",
            "enum": ["processing", "success", "error"],
            "description": "Estado de la factura"
          },
          "errorMessage": {
            "type": ["string", "null"],
            "description": "Motivo del error, si status es error"
          },
          "description": {
            "type": ["string", "null"],
            "description": "Descripción de la factura"
          },
          "issuedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo ARCA autorizó el comprobante. En las facturas emitidas desde Facturear es la fecha de creación; en las importadas desde ARCA, la fecha del comprobante. Los reportes agrupan por este campo"
          },
          "origin": {
            "type": "string",
            "enum": ["facturear", "arca"],
            "description": "facturear: emitida desde Facturear. arca: copiada de un comprobante que ARCA ya había autorizado (Importar desde ARCA)"
          },
          "voidedBy": {
            "type": ["string", "null"],
            "description": "ID de la nota de crédito que anuló esta factura (POST /invoices/{invoiceId}/credit-note), o null. Solo viene en GET /invoices"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          },
          "cuit": {
            "type": "object",
            "description": "CUIT emisor. persona solo viene en GET /invoices/{invoiceId}",
            "properties": {
              "number": {
                "type": "string",
                "description": "Número de CUIT",
                "example": "20-12345678-9"
              },
              "persona": {
                "type": ["object", "null"],
                "description": "Datos del padrón de ARCA del emisor"
              }
            }
          }
        }
      },
      "InvoiceResponse": {
        "type": "object",
        "description": "Las facturas quedan encoladas en un lote; consultá su resultado con GET /invoices/batches/{batchId}.",
        "required": ["batch", "message", "count", "status", "batchId", "queueIdentifiers"],
        "properties": {
          "batch": {
            "type": "boolean",
            "description": "false si se encoló una sola factura, true si fueron varias"
          },
          "message": {
            "type": "string",
            "description": "Mensaje de confirmación",
            "example": "Factura encolada para procesamiento"
          },
          "count": {
            "type": "integer",
            "description": "Cantidad de facturas encoladas",
            "example": 1
          },
          "status": {
            "type": "string",
            "enum": ["processing"],
            "description": "Estado del lote"
          },
          "batchId": {
            "type": "string",
            "description": "ID del lote creado"
          },
          "queueIdentifiers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Colas en las que se encolaron las facturas (una por entorno, CUIT, punto de venta y tipo de comprobante)"
          }
        }
      },
      "Meta": {
        "type": "object",
        "required": ["page", "limit", "totalCount", "totalPages", "hasNextPage", "hasPrevPage"],
        "properties": {
          "page": {
            "type": "integer",
            "example": 1,
            "description": "Página actual"
          },
          "limit": {
            "type": "integer",
            "example": 10,
            "description": "Elementos por página"
          },
          "totalCount": {
            "type": "integer",
            "example": 42,
            "description": "Total de elementos"
          },
          "totalPages": {
            "type": "integer",
            "example": 5,
            "description": "Total de páginas"
          },
          "hasNextPage": {
            "type": "boolean",
            "description": "Hay una página siguiente"
          },
          "hasPrevPage": {
            "type": "boolean",
            "description": "Hay una página anterior"
          }
        }
      },
      "Batch": {
        "type": "object",
        "required": [
          "id",
          "userId",
          "environment",
          "status",
          "totalItems",
          "processedItems",
          "successfulItems",
          "failedItems",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID del lote"
          },
          "userId": {
            "type": "string",
            "description": "ID del usuario"
          },
          "environment": {
            "type": "string",
            "enum": ["production", "homologation"],
            "description": "Entorno"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "processing", "completed", "completed_with_errors", "error"],
            "description": "Estado del lote"
          },
          "totalItems": {
            "type": "integer",
            "description": "Total de items en el lote"
          },
          "processedItems": {
            "type": "integer",
            "description": "Items procesados (con éxito o con error)"
          },
          "successfulItems": {
            "type": "integer",
            "description": "Items procesados con éxito"
          },
          "failedItems": {
            "type": "integer",
            "description": "Items que fallaron"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          },
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            },
            "description": "Items del lote"
          }
        }
      },
      "BatchDetail": {
        "type": "object",
        "required": [
          "id",
          "status",
          "totalItems",
          "processedItems",
          "successfulItems",
          "failedItems",
          "environment",
          "createdAt",
          "updatedAt",
          "items"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID del lote"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "processing", "completed", "completed_with_errors", "error"],
            "description": "Estado del lote"
          },
          "totalItems": {
            "type": "integer",
            "description": "Total de items en el lote"
          },
          "processedItems": {
            "type": "integer",
            "description": "Items procesados (con éxito o con error)"
          },
          "successfulItems": {
            "type": "integer",
            "description": "Items procesados con éxito"
          },
          "failedItems": {
            "type": "integer",
            "description": "Items que fallaron"
          },
          "environment": {
            "type": "string",
            "enum": ["production", "homologation"],
            "description": "Entorno"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          },
          "items": {
            "type": "array",
            "description": "Items del lote",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/BatchItem"
                },
                {
                  "type": "object",
                  "properties": {
                    "cuit": {
                      "type": ["object", "null"],
                      "description": "CUIT emisor del item",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "number": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "BatchItem": {
        "type": "object",
        "required": ["id", "status", "order", "createdAt", "updatedAt", "requestBody"],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID del item"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "processing", "completed", "error"],
            "description": "Estado del item"
          },
          "order": {
            "type": "integer",
            "description": "Posición del item en su cola"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          },
          "requestBody": {
            "type": "object",
            "description": "Factura encolada: los campos de InvoiceRequest ya completados con los valores por defecto del CUIT"
          },
          "responseBody": {
            "type": ["object", "null"],
            "description": "Resultado del procesamiento (la factura emitida o el detalle del error)"
          }
        }
      },
      "InvoiceBranding": {
        "type": "object",
        "properties": {
          "template": { "type": "string", "enum": ["clasico", "moderno", "minimalista", "elegante"], "description": "Plantilla visual. Por defecto clasico" },
          "paperSize": { "type": "string", "enum": ["A4", "LETTER", "LEGAL"], "description": "Tipo de hoja: A4 (por defecto), carta u oficio" },
          "accentColor": { "type": ["string", "null"], "pattern": "^#[0-9a-fA-F]{6}$", "description": "Color de acento #rrggbb. null usa el de la plantilla" },
          "logo": { "type": ["string", "null"], "description": "Logo como data URL (data:image/png|jpeg|webp;base64,...), hasta 512 KB" },
          "tradeName": { "type": ["string", "null"], "maxLength": 120, "description": "Nombre de fantasía" },
          "activityStart": { "type": ["string", "null"], "format": "date", "description": "Fecha de inicio de actividades (AAAA-MM-DD)" },
          "address": { "type": ["string", "null"], "maxLength": 200, "description": "Domicilio comercial, si difiere del domicilio fiscal del padrón" },
          "footerNote": { "type": ["string", "null"], "maxLength": 500, "description": "Texto libre al pie de la factura" }
        }
      },
      "Error": {
        "type": "object",
        "description": "Error de la API. Los errores de autenticación (401), validación (400), CUIT inexistente (404), conflicto (409) e internos (500) vienen como application/problem+json (RFC 9457) con code, message y resolution. Otros errores vienen como JSON con error y, a veces, details y code. En los dos casos está el campo error.",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "string",
            "description": "Mensaje de error"
          },
          "code": {
            "type": "string",
            "description": "Código estable: unauthorized, invalid_request, cuit_not_found, conflict, internal_error, o códigos propios como SUBSCRIPTION_LIMIT_EXCEEDED"
          },
          "message": {
            "type": "string",
            "description": "Qué pasó (problem+json)"
          },
          "resolution": {
            "type": "string",
            "description": "Qué hacer para resolverlo (problem+json)"
          },
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI del tipo de problema (problem+json)"
          },
          "title": {
            "type": "string",
            "description": "Título corto del problema (problem+json)"
          },
          "status": {
            "type": "integer",
            "description": "Código HTTP (problem+json)"
          },
          "detail": {
            "type": "string",
            "description": "Igual que message (problem+json)"
          },
          "details": {
            "description": "Detalle del error: un texto, o la lista de errores de validación"
          }
        }
      },
      "PointsOfSale": {
        "type": "object",
        "properties": {
          "pos": {
            "type": ["object", "null"],
            "properties": {
              "pos": {
                "description": "Respuesta de ARCA a FEParamGetPtosVenta guardada (ResultGet.PtoVenta con Nro, EmisionTipo, Bloqueado y FchBaja)"
              },
              "posLastUpdated": {
                "type": ["string", "null"],
                "format": "date-time",
                "description": "Última vez que se consultaron los puntos de venta en ARCA"
              },
              "default_pos": {
                "type": ["integer", "null"],
                "description": "Punto de venta por defecto"
              }
            }
          },
          "lastInvoices": {
            "type": "array",
            "description": "La última factura autorizada desde Facturear en cada punto de venta, en el entorno de la API key",
            "items": {
              "type": "object",
              "properties": {
                "ptoVta": {
                  "type": "integer"
                },
                "id": {
                  "type": "string",
                  "description": "ID de la factura"
                },
                "invoiceType": {
                  "type": ["integer", "null"]
                },
                "voucherNumber": {
                  "type": "integer"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "LastVoucher": {
        "type": "object",
        "properties": {
          "ptoVta": {
            "type": "integer",
            "description": "Punto de venta"
          },
          "invoiceType": {
            "type": "integer",
            "description": "Código de ARCA del tipo de comprobante"
          },
          "voucherNumber": {
            "type": "integer",
            "description": "Último número autorizado"
          },
          "date": {
            "type": ["string", "null"],
            "description": "Fecha del comprobante en ARCA (AAAA-MM-DD)"
          },
          "invoiceId": {
            "type": ["string", "null"],
            "description": "ID de la factura en Facturear, si se emitió desde Facturear"
          }
        }
      },
      "EmailDesign": {
        "type": "object",
        "description": "Diseño del mail con el que sale la factura de este CUIT. null = valor por defecto",
        "properties": {
          "accentColor": {
            "type": ["string", "null"],
            "pattern": "^#[0-9a-fA-F]{6}$",
            "description": "Color de la banda superior (#rrggbb)"
          },
          "backgroundColor": {
            "type": ["string", "null"],
            "pattern": "^#[0-9a-fA-F]{6}$",
            "description": "Color de fondo (#rrggbb)"
          },
          "showLogo": {
            "type": "boolean",
            "description": "Mostrar el logo del CUIT en el encabezado"
          },
          "subject": {
            "type": ["string", "null"],
            "maxLength": 200,
            "description": "Asunto. Admite bloques como %emisor%"
          },
          "body": {
            "type": ["string", "null"],
            "maxLength": 3000,
            "description": "Mensaje. Admite bloques como %cliente%"
          },
          "signature": {
            "type": ["string", "null"],
            "maxLength": 500,
            "description": "Firma. null = firma por defecto; texto vacío = sin firma"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "headers": {
            "type": ["object", "null"],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Headers propios que se agregan a cada envío"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEvent"
            }
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEvent": {
        "type": "string",
        "enum": ["delegation.completed", "invoice.completed", "invoice.failed", "batch.completed", "draft.review_required"]
      },
      "DraftData": {
        "type": "object",
        "description": "Los datos de la factura propuesta",
        "required": ["lines"],
        "properties": {
          "receiver": {
            "type": "object",
            "properties": {
              "name": {
                "type": ["string", "null"],
                "maxLength": 200
              },
              "docType": {
                "type": ["string", "null"],
                "description": "CUIT, CUIL o DNI; null = consumidor final sin identificar"
              },
              "docNumber": {
                "type": ["string", "null"],
                "description": "CUIT, CUIL o DNI, con o sin guiones"
              },
              "condicionIva": {
                "type": ["integer", "null"],
                "description": "Condición frente al IVA del receptor (código de ARCA). Si falta, se busca en el padrón"
              },
              "email": {
                "type": ["string", "null"],
                "format": "email",
                "description": "Si está, se le manda la factura"
              },
              "address": {
                "type": ["string", "null"],
                "maxLength": 300
              }
            }
          },
          "concepto": {
            "type": "integer",
            "enum": [1, 2, 3],
            "default": 1,
            "description": "1 productos, 2 servicios, 3 productos y servicios"
          },
          "serviceFrom": {
            "type": ["string", "null"],
            "format": "date",
            "description": "AAAA-MM-DD, servicios"
          },
          "serviceTo": {
            "type": ["string", "null"],
            "format": "date",
            "description": "AAAA-MM-DD, servicios"
          },
          "paymentDue": {
            "type": ["string", "null"],
            "format": "date",
            "description": "Vencimiento del pago, AAAA-MM-DD"
          },
          "pricesIncludeIva": {
            "type": "boolean",
            "default": true,
            "description": "Los precios de las líneas incluyen IVA"
          },
          "lines": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "type": "object",
              "required": ["description", "unitPrice"],
              "properties": {
                "description": {
                  "type": "string",
                  "maxLength": 200
                },
                "quantity": {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "default": 1
                },
                "unitPrice": {
                  "type": ["number", "null"],
                  "minimum": 0,
                  "description": "null si el documento no trae precio"
                },
                "ivaRate": {
                  "type": "number",
                  "enum": [0, 2.5, 5, 10.5, 21, 27],
                  "default": 21,
                  "description": "Alícuota de IVA en porcentaje"
                }
              }
            }
          },
          "documentTotal": {
            "type": ["number", "null"],
            "description": "Total impreso en el documento, para controlar las líneas"
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "default": "ARS",
            "description": "Moneda ISO 4217"
          },
          "documentDate": {
            "type": ["string", "null"],
            "format": "date",
            "description": "Fecha del documento, AAAA-MM-DD. La factura se emite con la fecha del día"
          },
          "reference": {
            "type": ["string", "null"],
            "maxLength": 100,
            "description": "Número de remito, pedido o referencia"
          },
          "description": {
            "type": ["string", "null"],
            "maxLength": 500,
            "description": "Texto libre que va en la factura"
          }
        }
      },
      "Draft": {
        "type": "object",
        "description": "Un borrador de factura armado desde un documento, una planilla, datos enviados por API o una plantilla recurrente",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["extracting", "review", "queued", "invoiced", "error", "discarded"],
            "description": "extracting: leyéndose; review: espera revisión; queued: enviado a ARCA; invoiced: facturado; error: no se pudo leer o emitir; discarded: descartado"
          },
          "mode": {
            "type": "string",
            "enum": ["manual", "automatic"],
            "description": "automatic: se emite solo si no hay observaciones"
          },
          "source": {
            "type": "string",
            "enum": ["upload", "google_drive", "zapier", "api", "recurring", "mcp", "whatsapp"]
          },
          "sourceRef": {
            "type": ["string", "null"]
          },
          "fileName": {
            "type": ["string", "null"]
          },
          "mimeType": {
            "type": ["string", "null"]
          },
          "hasFile": {
            "type": "boolean"
          },
          "templateId": {
            "type": ["string", "null"]
          },
          "templateName": {
            "type": ["string", "null"]
          },
          "cuitId": {
            "type": ["string", "null"]
          },
          "ptoVta": {
            "type": ["integer", "null"]
          },
          "environment": {
            "type": "string",
            "enum": ["production", "homologation"]
          },
          "data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DraftData"
              },
              {
                "type": "null"
              }
            ]
          },
          "total": {
            "type": ["number", "null"],
            "description": "Total calculado con las líneas; null si falta algún precio"
          },
          "voucherLetter": {
            "type": ["string", "null"],
            "enum": ["A", "B", "C", null]
          },
          "confidence": {
            "type": ["number", "null"],
            "description": "Confianza de la lectura con IA, de 0 a 1"
          },
          "issues": {
            "type": "array",
            "description": "Observaciones que hay que revisar",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": ["no_cuit", "no_lines", "missing_price", "invalid_amount", "total_mismatch", "invalid_document", "unidentified_receiver", "foreign_currency", "low_confidence", "possible_duplicate", "ai_note", "ai_info"]
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "errorMessage": {
            "type": ["string", "null"]
          },
          "invoice": {
            "type": ["object", "null"],
            "description": "La factura emitida desde el borrador",
            "properties": {
              "id": {
                "type": "string"
              },
              "voucherNumber": {
                "type": "integer"
              },
              "ptoVta": {
                "type": ["integer", "null"]
              },
              "invoiceType": {
                "type": ["integer", "null"]
              },
              "status": {
                "type": "string"
              },
              "amount": {
                "type": "number"
              }
            }
          },
          "emailStatus": {
            "type": ["string", "null"],
            "description": "Estado del envío de la factura por email"
          },
          "url": {
            "type": "string",
            "description": "Link al borrador en el dashboard"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TemplateInput": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "cuitId": {
            "type": ["string", "null"],
            "description": "CUIT emisor. Obligatorio en modo automático y en las recurrentes"
          },
          "ptoVta": {
            "type": ["integer", "null"],
            "minimum": 1,
            "maximum": 99999
          },
          "mode": {
            "type": "string",
            "enum": ["manual", "automatic"],
            "default": "manual"
          },
          "concepto": {
            "type": "integer",
            "enum": [1, 2, 3],
            "default": 1
          },
          "ivaRate": {
            "type": "number",
            "enum": [0, 2.5, 5, 10.5, 21, 27],
            "default": 21
          },
          "pricesIncludeIva": {
            "type": "boolean",
            "default": true
          },
          "receiverDocType": {
            "type": ["string", "null"],
            "enum": ["CUIT", "CUIL", "DNI", null],
            "description": "Cliente fijo: todas las facturas de la plantilla van a él"
          },
          "receiverDocNumber": {
            "type": ["string", "null"],
            "maxLength": 20
          },
          "receiverName": {
            "type": ["string", "null"],
            "maxLength": 200
          },
          "receiverCondicionIva": {
            "type": ["integer", "null"]
          },
          "receiverEmail": {
            "type": ["string", "null"],
            "format": "email"
          },
          "items": {
            "type": ["array", "null"],
            "maxItems": 100,
            "description": "Líneas fijas, para las facturas recurrentes",
            "items": {
              "type": "object",
              "required": ["description", "quantity", "unitPrice"],
              "properties": {
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unitPrice": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          },
          "priceList": {
            "type": ["array", "null"],
            "maxItems": 2000,
            "description": "Precios para documentos que no los traen (remitos)",
            "items": {
              "type": "object",
              "required": ["description", "unitPrice"],
              "properties": {
                "description": {
                  "type": "string"
                },
                "unitPrice": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          },
          "instructions": {
            "type": ["string", "null"],
            "maxLength": 4000,
            "description": "Lo que la IA tiene que saber para leer este tipo de documento"
          },
          "columnMapping": {
            "type": ["object", "null"],
            "description": "Columnas de la planilla → campos de la factura",
            "properties": {
              "headerRow": {
                "type": "integer",
                "minimum": 1
              },
              "columns": {
                "type": "object",
                "description": "Campo → nombre de la columna. Campos: receiverName, receiverDoc, receiverEmail, receiverCondicionIva, receiverAddress, description, quantity, unitPrice, lineTotal, ivaRate, reference, date, concepto",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "groupBy": {
                "type": ["string", "null"]
              },
              "pricesIncludeIva": {
                "type": "boolean"
              }
            }
          },
          "paymentTermDays": {
            "type": ["integer", "null"],
            "minimum": 0,
            "maximum": 365
          },
          "sendEmail": {
            "type": "boolean",
            "default": true,
            "description": "Mandarle la factura al cliente por email"
          },
          "emailCopyTo": {
            "type": ["string", "null"],
            "format": "email"
          },
          "recurrence": {
            "type": ["string", "null"],
            "enum": ["monthly", null],
            "description": "monthly: emite las líneas fijas todos los meses en dayOfMonth"
          },
          "dayOfMonth": {
            "type": ["integer", "null"],
            "minimum": 1,
            "maximum": 28
          },
          "active": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "cuitId": {
            "type": ["string", "null"],
            "description": "CUIT emisor. Obligatorio en modo automático y en las recurrentes"
          },
          "ptoVta": {
            "type": ["integer", "null"],
            "minimum": 1,
            "maximum": 99999
          },
          "mode": {
            "type": "string",
            "enum": ["manual", "automatic"],
            "default": "manual"
          },
          "concepto": {
            "type": "integer",
            "enum": [1, 2, 3],
            "default": 1
          },
          "ivaRate": {
            "type": "number",
            "enum": [0, 2.5, 5, 10.5, 21, 27],
            "default": 21
          },
          "pricesIncludeIva": {
            "type": "boolean",
            "default": true
          },
          "receiverDocType": {
            "type": ["string", "null"],
            "enum": ["CUIT", "CUIL", "DNI", null],
            "description": "Cliente fijo: todas las facturas de la plantilla van a él"
          },
          "receiverDocNumber": {
            "type": ["string", "null"],
            "maxLength": 20
          },
          "receiverName": {
            "type": ["string", "null"],
            "maxLength": 200
          },
          "receiverCondicionIva": {
            "type": ["integer", "null"]
          },
          "receiverEmail": {
            "type": ["string", "null"],
            "format": "email"
          },
          "items": {
            "type": ["array", "null"],
            "maxItems": 100,
            "description": "Líneas fijas, para las facturas recurrentes",
            "items": {
              "type": "object",
              "required": ["description", "quantity", "unitPrice"],
              "properties": {
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unitPrice": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          },
          "priceList": {
            "type": ["array", "null"],
            "maxItems": 2000,
            "description": "Precios para documentos que no los traen (remitos)",
            "items": {
              "type": "object",
              "required": ["description", "unitPrice"],
              "properties": {
                "description": {
                  "type": "string"
                },
                "unitPrice": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          },
          "instructions": {
            "type": ["string", "null"],
            "maxLength": 4000,
            "description": "Lo que la IA tiene que saber para leer este tipo de documento"
          },
          "columnMapping": {
            "type": ["object", "null"],
            "description": "Columnas de la planilla → campos de la factura",
            "properties": {
              "headerRow": {
                "type": "integer",
                "minimum": 1
              },
              "columns": {
                "type": "object",
                "description": "Campo → nombre de la columna. Campos: receiverName, receiverDoc, receiverEmail, receiverCondicionIva, receiverAddress, description, quantity, unitPrice, lineTotal, ivaRate, reference, date, concepto",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "groupBy": {
                "type": ["string", "null"]
              },
              "pricesIncludeIva": {
                "type": "boolean"
              }
            }
          },
          "paymentTermDays": {
            "type": ["integer", "null"],
            "minimum": 0,
            "maximum": 365
          },
          "sendEmail": {
            "type": "boolean",
            "default": true,
            "description": "Mandarle la factura al cliente por email"
          },
          "emailCopyTo": {
            "type": ["string", "null"],
            "format": "email"
          },
          "recurrence": {
            "type": ["string", "null"],
            "enum": ["monthly", null],
            "description": "monthly: emite las líneas fijas todos los meses en dayOfMonth"
          },
          "dayOfMonth": {
            "type": ["integer", "null"],
            "minimum": 1,
            "maximum": 28
          },
          "active": {
            "type": "boolean",
            "default": true
          },
          "nextRunAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "lastRunAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ArcaImport": {
        "type": "object",
        "description": "Un relevamiento de los comprobantes que ARCA ya autorizó para un CUIT, y su importación a Facturear",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["scanning", "ready", "importing", "done", "error", "cancelled"],
            "description": "scanning: relevando; ready: relevado, listo para importar; importing: importando; done, error o cancelled"
          },
          "range": {
            "type": "string",
            "enum": ["mes", "anio", "anio-pasado"]
          },
          "rangeLabel": {
            "type": "string"
          },
          "from": {
            "type": ["string", "null"],
            "description": "Primer día incluido (DD/MM/AAAA)"
          },
          "to": {
            "type": ["string", "null"],
            "description": "Último día incluido (DD/MM/AAAA)"
          },
          "imported": {
            "type": "integer"
          },
          "skipped": {
            "type": "integer"
          },
          "gaps": {
            "type": "integer"
          },
          "errorMessage": {
            "type": ["string", "null"]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "pointsOfSale": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "segments": {
            "type": "array",
            "description": "Un tramo por punto de venta y tipo de comprobante",
            "items": {
              "type": "object",
              "properties": {
                "ptoVta": {
                  "type": "integer"
                },
                "cbteTipo": {
                  "type": "integer"
                },
                "cbteTipoName": {
                  "type": "string"
                },
                "lastNumber": {
                  "type": "integer"
                },
                "fromNumber": {
                  "type": ["integer", "null"]
                },
                "toNumber": {
                  "type": ["integer", "null"]
                },
                "fromDate": {
                  "type": ["string", "null"]
                },
                "toDate": {
                  "type": ["string", "null"]
                },
                "inRange": {
                  "type": "integer"
                },
                "already": {
                  "type": "integer",
                  "description": "Ya estaban en Facturear"
                },
                "pending": {
                  "type": "integer"
                },
                "note": {
                  "type": ["string", "null"]
                },
                "resolved": {
                  "type": "boolean"
                }
              }
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "inRange": {
                "type": "integer"
              },
              "already": {
                "type": "integer"
              },
              "pending": {
                "type": "integer"
              }
            }
          },
          "scan": {
            "type": ["object", "null"],
            "description": "Avance del relevamiento; null cuando terminó",
            "properties": {
              "phase": {
                "type": "string",
                "enum": ["puntos", "numeracion", "fechas"]
              },
              "done": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "cursor": {
            "type": ["object", "null"],
            "description": "Por dónde va la importación",
            "properties": {
              "ptoVta": {
                "type": "integer"
              },
              "cbteTipoName": {
                "type": "string"
              },
              "next": {
                "type": "integer"
              },
              "toNumber": {
                "type": "integer"
              }
            }
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Clave que elegís vos (recomendado: un UUID nuevo por cada factura o lote). Si reenviás la misma solicitud con la misma clave —por un timeout, un error de red o un 5xx— recibís la respuesta original (mismo `batchId`, header `Idempotent-Replayed: true`) en vez de una factura nueva. Para una factura distinta, o después de que ARCA rechazó la anterior en forma definitiva, usá una clave nueva. Entre 1 y 255 caracteres ASCII imprimibles; se guarda 7 días. En un lote, el ítem `i` queda identificado como `<clave>:<i>`.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "example": "6f1c2b0e-8a43-4c5e-9d2a-3b7f1e0c9a11"
      }
    },
    "headers": {
      "IdempotentReplayed": {
        "description": "`true` cuando la respuesta es la guardada de una solicitud anterior con el mismo `Idempotency-Key`: no se encoló nada nuevo.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      }
    },
    "responses": {
      "IdempotencyInProgress": {
        "description": "Ya hay una solicitud en curso con este `Idempotency-Key` (code `IDEMPOTENCY_KEY_IN_PROGRESS`). Esperá unos segundos y reintentá con la misma clave para recibir su resultado.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "IdempotencyKeyReused": {
        "description": "Este `Idempotency-Key` ya se usó con otra solicitud: otro cuerpo u otro endpoint (code `IDEMPOTENCY_KEY_REUSED`). Usá una clave nueva para una factura distinta.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API Key para autenticación. Formato: test_sk_xxx para testing, prod_sk_xxx para producción."
      }
    }
  }
}
