{
  "openapi": "3.0.0",
  "info": {
    "title": "Tupana API — v2",
    "description": "API v2 de Tupana: facturación electrónica, cesiones, recaudación, consultas, boleta de honorarios y nómina. Los identificadores de recursos son public IDs opacos con prefijo (docu_, ment_, cred_, doce_, empl_…).",
    "version": "2.0.0"
  },
  "servers": [
    {
      "url": "https://api.tupana.ai/v2",
      "description": "Producción (v2)"
    }
  ],
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "paths": {
    "/book-summaries/": {
      "get": {
        "operationId": "listBookSummaries_v2",
        "tags": [
          "Libros SII"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar resumen de libro de compras/ventas SII",
        "description": "Obtiene el resumen de libro de compras y ventas (getResumen del SII) para una entidad y período. Es data agregada por tipo de documento y operación (COMPRA/VENTA), no el detalle línea a línea. Solo devuelve datos para entidades habilitadas explícitamente para este scrape (ver `is_enabled` en la respuesta); si la entidad no está habilitada, `results` viene vacío.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
            "schema": {
              "type": "string",
              "example": "ment_4829301923847"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "description": "Período a consultar, formato YYYYMM.",
            "schema": {
              "type": "string",
              "example": "202603"
            }
          },
          {
            "name": "operation",
            "in": "query",
            "required": false,
            "description": "Filtra por operación: COMPRA o VENTA. Si se omite, devuelve ambas.",
            "schema": {
              "type": "string",
              "enum": [
                "COMPRA",
                "VENTA"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resumen de libro para la entidad y período consultado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BookSummaryItem"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        },
                        "is_enabled": {
                          "type": "boolean",
                          "description": "true si la entidad tiene habilitado el scrape de resumen de libros (BOOK_SUMMARY). Si es false, `data` estará vacío aunque el período sea válido."
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "master_entity_id faltante o inválido, o period faltante o con formato inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "period is required in YYYYMM format."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad, o la API key no tiene el permiso book_summary:access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Access denied."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cessions/{id}/": {
      "get": {
        "operationId": "getCession_v2",
        "tags": [
          "Cesiones"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Obtener una cesión",
        "description": "Obtiene el detalle de una cesión por ID. Es accesible tanto si tienes acceso a la entidad emisora como a la receptora del documento cedido. Si se envía el parámetro pdf=document-cession, la respuesta es el PDF del certificado de cesión servido inline (200, Content-Type application/pdf) en vez del JSON — se lee del caché en S3 si ya existe, o se scrapea del SII en el momento (requiere que Tupana administre la credencial SII del emisor de la factura). Por defecto (sin el parámetro) devuelve el JSON con el detalle de la cesión.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la cesión",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "pdf",
            "in": "query",
            "required": false,
            "description": "Si se envía el valor document-cession, la respuesta es el PDF del certificado de cesión servido inline (no JSON, no redirect). Útil para descargar o mostrar el certificado directamente.",
            "schema": {
              "type": "string",
              "enum": [
                "document-cession"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sin pdf=document-cession: detalle de la cesión (JSON), incluye eventos de trazabilidad y errores si existen. Con pdf=document-cession: el PDF del certificado de cesión servido inline, reemplazando la respuesta JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Objeto cesión con todos los campos del listado más events y errors",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "document_id": {
                      "type": "integer"
                    },
                    "document_folio": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string"
                    },
                    "assignee_business_name": {
                      "type": "string"
                    },
                    "assignment_amount": {
                      "type": "number"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "event_code": {
                            "type": "string"
                          },
                          "event_description": {
                            "type": "string"
                          },
                          "event_date": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "No tienes acceso a esta cesión",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Cesión no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Error al obtener el certificado (credencial SII o scraping)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cessions/batch/": {
      "post": {
        "operationId": "createCessionBatch_v2",
        "tags": [
          "Cesiones"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Generar cesiones de facturas en lote",
        "description": "Genera cesiones (AECs) de múltiples facturas en una sola llamada. Obtiene automáticamente los códigos EHDR del SII y envía los AECs al SII.",
        "requestBody": {
          "description": "Datos para generar las cesiones",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "master_entity_id",
                  "document_ids",
                  "assignee_rut",
                  "assignee_dv",
                  "assignee_business_name",
                  "assignee_address",
                  "assignee_email"
                ],
                "properties": {
                  "master_entity_id": {
                    "type": "integer",
                    "description": "ID de la entidad maestra emisora de las facturas",
                    "example": 123
                  },
                  "document_ids": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Lista de IDs de los documentos (facturas) a ceder",
                    "example": [
                      858405,
                      858406
                    ]
                  },
                  "assignee_rut": {
                    "type": "string",
                    "description": "RUT del cesionario (sin puntos ni guión)",
                    "example": "76798398"
                  },
                  "assignee_dv": {
                    "type": "string",
                    "description": "Dígito verificador del RUT del cesionario",
                    "example": "0"
                  },
                  "assignee_business_name": {
                    "type": "string",
                    "description": "Razón social del cesionario",
                    "example": "SUPLO SPA"
                  },
                  "assignee_address": {
                    "type": "string",
                    "description": "Dirección del cesionario",
                    "example": "Av. Tajamar 183"
                  },
                  "assignee_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email del cesionario",
                    "example": "factoring@suplo.cl"
                  },
                  "assignor_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email del cedente (opcional, se usa el email de la entidad si no se proporciona)",
                    "example": "antonio@tupana.ai"
                  }
                }
              },
              "example": {
                "master_entity_id": "ment_4829301923847",
                "document_ids": [
                  "docu_9f2a7c1b8e4d0",
                  "docu_9f2a7c1b8e4d0"
                ],
                "assignee_rut": "76798398",
                "assignee_dv": "0",
                "assignee_business_name": "SUPLO SPA",
                "assignee_address": "Av. Tajamar 183",
                "assignee_email": "factoring@suplo.cl",
                "assignor_email": "antonio@tupana.ai"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Solicitud aceptada y encolada. La generación real de las cesiones corre en segundo plano — este 202 NO confirma que las cesiones se hayan generado exitosamente, solo que la solicitud fue validada y aceptada. Usa `cession_batch_id` para consultar el resultado final en GET /cessions/batches/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "status": {
                      "type": "string",
                      "example": "processing"
                    },
                    "ws_channel": {
                      "type": "string",
                      "description": "Canal WebSocket donde se publica el avance en tiempo real (opcional de escuchar)",
                      "example": "cessions-70193"
                    },
                    "total": {
                      "type": "integer",
                      "description": "Cantidad de documentos incluidos en el lote",
                      "example": 2
                    },
                    "message": {
                      "type": "string",
                      "example": "Generando las cesiones y enviándolas al SII…"
                    },
                    "cession_batch_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID del lote creado. Consúltalo con GET /cessions/batches/{id} para conocer el resultado (éxito, fallo o parcial) de cada documento.",
                      "example": "e7877303-1a03-424d-a024-48c1de218611"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "status": "processing",
                  "ws_channel": "cessions-70193",
                  "total": 2,
                  "message": "Generando las cesiones y enviándolas al SII…",
                  "cession_batch_id": "e7877303-1a03-424d-a024-48c1de218611"
                }
              }
            }
          },
          "400": {
            "description": "Error en los datos proporcionados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "invalid_documents": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                },
                "examples": {
                  "missing_master_entity_id": {
                    "value": {
                      "error": "master_entity_id is required in the request body"
                    }
                  },
                  "missing_fields": {
                    "value": {
                      "error": "Missing required fields: assignee_rut, assignee_dv, assignee_email"
                    }
                  },
                  "invalid_documents": {
                    "value": {
                      "error": "Only electronic invoices (DTE 33) or exempt invoices (DTE 34) can be assigned",
                      "invalid_documents": [
                        {
                          "id": "doce_7c3e9a1f5b2d8",
                          "folio": 12347,
                          "dte_code": "39"
                        }
                      ]
                    }
                  },
                  "missing_credentials": {
                    "value": {
                      "error": "No se encontraron credenciales SII válidas para esta entidad. La cesión requiere una credencial SII personal."
                    },
                    "description": "Las cesiones se generan usando la contraseña del SII del representante legal, no con el certificado digital. Se requiere una credencial SII personal válida."
                  }
                }
              }
            }
          },
          "403": {
            "description": "No tienes acceso a esta entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Documentos no encontrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Some documents were not found or don't belong to this entity"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "missing_folios": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cessions/": {
      "get": {
        "operationId": "listCessions_v2",
        "tags": [
          "Cesiones"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar cesiones (emitidas o recibidas)",
        "description": "Obtiene las cesiones de facturas (AEC) de una entidad. Las cesiones son las transferencias de derechos de crédito de facturas a un cesionario (por ejemplo una empresa de factoring). Por defecto devuelve las cesiones EMITIDAS por la entidad (document_type=issued); con document_type=received devuelve las cesiones RECIBIDAS — facturas de sus proveedores que ellos cedieron a un tercero, útil para saber a quién pagarle en vez del proveedor original.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "description": "ID de la entidad maestra. Su rol en las facturas cedidas (emisora o receptora) depende de document_type. Obligatorio.",
            "schema": {
              "type": "integer",
              "example": 123
            }
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "description": "issued (default) = cesiones donde master_entity_id es la EMISORA de la factura cedida. received = cesiones donde master_entity_id es la RECEPTORA de la factura cedida (facturas de proveedores cedidas por ellos a un tercero).",
            "schema": {
              "type": "string",
              "enum": [
                "issued",
                "received"
              ],
              "default": "issued"
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Fecha desde (YYYY-MM-DD) para filtrar por fecha de creación de la cesión.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Fecha hasta (YYYY-MM-DD) para filtrar por fecha de creación de la cesión.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Estado en el SII: processing, rejected o success.",
            "schema": {
              "type": "string",
              "enum": [
                "processing",
                "rejected",
                "success"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Búsqueda en folio del documento, nombre o RUT del emisor, o razón social/RUT del cesionario.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Número de página (paginación).",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "Cantidad de resultados por página.",
            "schema": {
              "type": "integer",
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista paginada de cesiones",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CessionListItem"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "master_entity_id faltante o inválido, o document_type con un valor distinto de issued/received",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "master_entity_id": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "No tienes acceso a esta entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cessions/batch/{batch_id}/": {
      "get": {
        "operationId": "getCessionBatchStatus_v2",
        "tags": [
          "Cesiones"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Consultar el estado de un lote de cesión",
        "description": "Obtiene el estado agregado de un lote creado con POST /cessions/batch (identificado por el cession_batch_id recibido en el 202), junto con el detalle por documento — incluyendo el mensaje de error real del SII si alguna cesión falló. No requiere master_entity_id: el lote ya sabe a qué entidad pertenece.",
        "parameters": [
          {
            "name": "batch_id",
            "in": "path",
            "required": true,
            "description": "cession_batch_id devuelto por POST /cessions/batch",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado del lote y detalle por documento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing",
                        "completed",
                        "failed",
                        "partial"
                      ],
                      "description": "completed = todos los documentos se cedieron con éxito. failed = ninguno. partial = una mezcla."
                    },
                    "total": {
                      "type": "integer"
                    },
                    "success_count": {
                      "type": "integer"
                    },
                    "failed_count": {
                      "type": "integer"
                    },
                    "assignee_business_name": {
                      "type": "string"
                    },
                    "assignee_rut": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "error_message": {
                      "type": "string",
                      "nullable": true,
                      "description": "Error general del lote (ej. sin credenciales SII válidas), si aplica"
                    },
                    "batch_cessions": {
                      "type": "array",
                      "description": "Un item por documento incluido en el lote",
                      "items": {
                        "type": "object",
                        "properties": {
                          "document_id": {
                            "type": "integer"
                          },
                          "folio": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "processing",
                              "success",
                              "failed"
                            ]
                          },
                          "cession_id": {
                            "type": "integer",
                            "nullable": true,
                            "description": "ID de la DocumentCession creada, solo si status=success"
                          },
                          "error_message": {
                            "type": "string",
                            "nullable": true,
                            "description": "Mensaje real del último intento fallido contra el SII, si status=failed"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "id": "e7877303-1a03-424d-a024-48c1de218611",
                  "status": "failed",
                  "total": 1,
                  "success_count": 0,
                  "failed_count": 1,
                  "assignee_business_name": "CAPITAL EXPRESS SERVICIOS FINANCIEROS SA.",
                  "assignee_rut": "76083507-2",
                  "created_at": "2026-08-05T20:18:53.703Z",
                  "error_message": null,
                  "batch_cessions": [
                    {
                      "document_id": "docu_9f2a7c1b8e4d0",
                      "folio": "674",
                      "status": "failed",
                      "cession_id": null,
                      "error_message": "Error al contribuyente. Código SII: 02.35.209.54.211.2"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "No tienes acceso a este lote de cesión",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Lote no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/documents/{document_id}/states/": {
      "get": {
        "operationId": "listDocumentStates_v2",
        "tags": [
          "Estados de Documentos"
        ],
        "summary": "Consultar historial de estados de un documento",
        "description": "Consultar el historial de estados asociados a un documento tributario específico.",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "description": "ID único del documento (integer)",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historial de estados obtenido exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentStatesResponse"
                }
              }
            }
          },
          "401": {
            "description": "No autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a este documento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "No tienes acceso a este documento"
                }
              }
            }
          },
          "404": {
            "description": "Documento no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Estados de Documentos"
        ],
        "summary": "Registrar nuevo estado en un documento",
        "description": "Registrar un nuevo estado cuando ocurre un evento relevante sobre el documento. Admite eventos del SII (ERM, ACD, RCD, RFT, RFP) y eventos internos de cobranza: **PAID** (marcar factura emitida como pagada) y **UNPAID** (marcar como no pagada). Para PAID y UNPAID solo el emisor del documento puede usarlos; aplican a facturas emitidas (tipo 33, 34, 39, 41). PAID genera un asiento contable de cierre de cuentas por cobrar (CxC); UNPAID revierte ese asiento si existe. También admite **ANNULLED** para anular una guía de despacho (DTE 52) emitida con folio, con `reason` obligatorio (Res. Ex. SII N°154: la guía que se reemplaza por otra queda registrada como anulada). Solo el emisor; la respuesta indica en `annulment.registry` dónde queda registrada la anulación: `delivery_note_book` (Libro de Guías, facturador de mercado) o `portal_follow_up` (facturador gratuito del SII: además hay que anotarla en \"Seguimiento del documento\" del portal mientras el SII no habilite el Registro de Guías). Errores 400 con `code`: `annulment_only_for_delivery_notes`, `annulment_only_for_issued_delivery_notes`, `annulment_reason_required`.",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "description": "ID único del documento (integer)",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentStateRequest"
              },
              "examples": {
                "acuse_recibo": {
                  "summary": "Registrar acuse de recibo",
                  "value": {
                    "event_code": "ERM"
                  }
                },
                "rechazo": {
                  "summary": "Registrar rechazo",
                  "value": {
                    "event_code": "RCD",
                    "rejection_reason": "Error en el monto facturado"
                  }
                },
                "aceptacion_contenido": {
                  "summary": "Aceptar contenido del documento",
                  "value": {
                    "event_code": "ACD"
                  }
                },
                "marcar_como_pagado": {
                  "summary": "Marcar factura como pagada (PAID)",
                  "description": "Solo emisor; factura emitida (33, 34, 39, 41). Genera asiento de cierre CxC.",
                  "value": {
                    "event_code": "PAID"
                  }
                },
                "marcar_como_no_pagado": {
                  "summary": "Marcar factura como no pagada (UNPAID)",
                  "description": "Solo emisor; revierte el asiento de cierre CxC si existe.",
                  "value": {
                    "event_code": "UNPAID"
                  }
                },
                "anular_guia": {
                  "summary": "Anular guía de despacho (ANNULLED)",
                  "description": "Solo emisor; guía (DTE 52) emitida con folio. Res. Ex. SII N°154. La respuesta trae annulment.registry y annulment.registry_note.",
                  "value": {
                    "event_code": "ANNULLED",
                    "reason": "Reemplazada por guía folio 1051: cambió la cantidad de bultos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estado registrado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentStateResponse"
                },
                "examples": {
                  "respuesta_paid": {
                    "summary": "Respuesta al marcar como pagado (PAID)",
                    "value": {
                      "success": true,
                      "event_registered": true,
                      "message": "Documento marcado como pagado. Se generó el asiento contable de cierre de cuentas por cobrar.",
                      "document": {
                        "id": "docu_9f2a7c1b8e4d0",
                        "folio": "42",
                        "date_issued": "2025-01-15",
                        "document_status": {
                          "paid_status": "PAID"
                        }
                      }
                    }
                  },
                  "respuesta_unpaid": {
                    "summary": "Respuesta al marcar como no pagado (UNPAID)",
                    "value": {
                      "success": true,
                      "event_registered": true,
                      "message": "Documento marcado como no pagado. Se revirtió el asiento de cierre de cuentas por cobrar.",
                      "document": {
                        "id": "docu_9f2a7c1b8e4d0",
                        "folio": "42",
                        "document_status": {
                          "paid_status": "NOT_PAID"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parámetros inválidos o error al registrar el evento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "parametros_faltantes": {
                    "value": {
                      "error": "Se requiere el código del evento (event_code)"
                    }
                  },
                  "evento_invalido": {
                    "value": {
                      "error": "Código de evento inválido. Debe ser uno de: ERM, ACD, RCD, RFT, RFP, PAID, UNPAID"
                    }
                  },
                  "error_sii": {
                    "value": {
                      "success": false,
                      "error": "Error al registrar evento en el SII",
                      "error_code": "SII_ERROR_CODE"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a este documento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Documento no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/documents/{document_id}/": {
      "get": {
        "operationId": "getDocument_v2",
        "tags": [
          "Documentos"
        ],
        "summary": "Obtener documento específico",
        "description": "Obtiene toda la información completa de un documento tributario específico, incluyendo:\n\n- **PDF y XML** cuando están disponibles (el PDF siempre se incluye en la respuesta, campo `pdf_url`)\n- **Detalles (productos/líneas)** del documento (campo `details`)\n- **Header completo** con información de transacción, pago y tipo de compra (campo `header`)\n- **Información del emisor** completa (campo `document_issuer`)\n- **Información del receptor** completa (campo `document_receiver`)\n- **Referencias** a otros documentos, como notas de crédito (campo `references`)\n\nEste endpoint es útil para consultar detalles completos de un documento ya emitido o recibido.\n\n**Seguridad:** El usuario solo puede acceder al documento si es emisor (sender) o receptor (receiver) del documento. Si el usuario no tiene acceso, se retorna un error 403 Forbidden.",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "description": "ID único del documento a consultar (entero)",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento obtenido exitosamente con toda la información completa: PDF, XML, detalles (productos), header, información del emisor y receptor, y referencias",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetailWithFiles"
                }
              }
            }
          },
          "400": {
            "description": "Parámetros inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "API Key faltante o inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder al documento. El usuario debe ser emisor (sender) o receptor (receiver) del documento.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "No tienes acceso a este documento"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Documento o entidad no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/documents/batch/": {
      "post": {
        "operationId": "createDocumentsBatch_v2",
        "summary": "Envío de documentos en lote",
        "description": "Crea hasta 200 documentos en una sola llamada. La respuesta incluye información completa de cada documento creado, incluyendo PDF cuando está disponible. Los resultados también se enviarán por webhook si está configurado.\n\n**Permisos requeridos:** La API Key debe tener el permiso `document:create` o permisos completos (`*`). Además, la entidad emisora debe tener credenciales SII válidas configuradas.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Previene lotes duplicados (≤ 256 caracteres, expira después de 24 h)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Use-Defaults",
            "in": "header",
            "description": "Si se establece como true, el sistema usará valores por defecto para campos no proporcionados:\n- Fecha actual para date_issued\n- Datos del emisor según configuración de la plataforma o primera actividad/dirección disponible\n- Datos del receptor según configuración del cliente o primera actividad/dirección disponible\n- Payment method = '2' (crédito) en el header del documento",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "description": "Lote de documentos a crear",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentBatch"
              },
              "example": {
                "documents": [
                  {
                    "dte_type": {
                      "code": "33"
                    },
                    "date_issued": "2024-01-15",
                    "document_issuer": {
                      "rut": "12345678-9",
                      "business_name": "Mi Empresa SpA"
                    },
                    "document_receiver": {
                      "rut": "98765432-1",
                      "business_name": "Cliente Importante Ltda"
                    },
                    "details": [
                      {
                        "item_name": "Servicio de Consultoría",
                        "quantity": 1,
                        "unit_price": 100000
                      }
                    ]
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Solicitud de creación de documentos aceptada. Los resultados se enviarán por webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                },
                "example": {
                  "batch_id": "550e8400-e29b-41d4-a716-446655440000",
                  "status": "processing",
                  "created_at": "2024-01-15T10:30:00Z",
                  "documents": [
                    {
                      "index": 0,
                      "status": "created",
                      "document": {
                        "id": "docu_9f2a7c1b8e4d0",
                        "folio": "1",
                        "date_issued": "2024-01-15",
                        "amount_with_iva": 119000.0,
                        "receiver_id": "ment_4829301923847",
                        "is_draft": false,
                        "can_be_issued": true,
                        "dte_type": {
                          "code": "33",
                          "description": "Factura Electrónica"
                        },
                        "sender": {
                          "id": "ment_4829301923847",
                          "name": "Mi Empresa SpA",
                          "tax_id": "12345678-9"
                        },
                        "receiver": {
                          "id": "ment_4829301923847",
                          "name": "Cliente Importante Ltda",
                          "tax_id": "98765432-1"
                        },
                        "items": [
                          {
                            "item_name": "Servicio de Consultoría",
                            "item_description": null,
                            "quantity": 1.0,
                            "unit_price": 100000.0,
                            "unit": "UN",
                            "item_code": null,
                            "item_type_code": null,
                            "discount_percent": null,
                            "other_tax": null
                          }
                        ],
                        "document_total": {
                          "net_amount": 100000.0,
                          "iva_rate": 19.0,
                          "iva_amount": 19000.0,
                          "total_amount": 119000.0
                        },
                        "pdf_url": "https://s3.amazonaws.com/bucket/documento_12345.pdf?signature=...",
                        "pdf_download_url": "/api/master-entities/123/documents/12345/file/"
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para crear documentos. La API Key debe tener el permiso 'document:create' o permisos completos ('*'). Además, la entidad emisora debe tener credenciales SII válidas configuradas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Esta entidad no tiene credenciales SII válidas configuradas"
                }
              }
            }
          },
          "413": {
            "description": "Más de 200 documentos en el array",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Cuerpo malformado o fallo de validación",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/documents/": {
      "get": {
        "operationId": "listDocuments_v2",
        "tags": [
          "Documentos"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar documentos",
        "description": "Obtiene las listas de documentos emitidos o recibidos por una entidad específica. Soporta búsqueda por folio, nombre del receptor y filtros avanzados.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad emisora o receptora cuyos documentos quieres consultar. El public ID de la entidad (`ment_...`).",
            "required": true,
            "schema": {
              "type": "string",
              "example": "ment_4829301923847"
            }
          },
          {
            "name": "document_type",
            "in": "query",
            "description": "`issued` (por defecto) o `received`. `issued` devuelve documentos donde la entidad es el **emisor**. `received` devuelve documentos donde la entidad es el **receptor** (cuando usas `received`, el parámetro `search` buscará en el nombre y RUT del emisor, y `issuer_tax_id` permite filtrar por RUT del emisor específico).",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "issued",
                "received"
              ],
              "default": "issued"
            }
          },
          {
            "name": "folio",
            "in": "query",
            "description": "Folio exacto del documento. Si se envía, se ignoran otros filtros y se devuelve el documento específico.",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Busca por nombre o RUT del receptor (cuando `document_type=issued`) o del emisor (cuando `document_type=received`).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dte_type__code__in",
            "in": "query",
            "description": "Lista de códigos DTE separados por coma (ej: 33,34). Opcional: si no se envía, se devuelven todos los tipos según document_type (emitidos o recibidos).",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "issuer_tax_id",
            "in": "query",
            "description": "RUT del emisor cuando `document_type=received`.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "issue_date_gte",
            "in": "query",
            "description": "Fecha de emisión mínima (inclusive) en formato `YYYY-MM-DD`. Filtra documentos cuya fecha de emisión (`date_issued`) sea igual o posterior a esta fecha. Ejemplo: `issue_date_gte=2026-01-01` devuelve documentos emitidos desde el 1 de enero de 2026 en adelante.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-01-01"
          },
          {
            "name": "issue_date_lte",
            "in": "query",
            "description": "Fecha de emisión máxima (inclusive) en formato `YYYY-MM-DD`. Filtra documentos cuya fecha de emisión (`date_issued`) sea igual o anterior a esta fecha. Ejemplo: `issue_date_lte=2026-01-31` devuelve documentos emitidos hasta el 31 de enero de 2026. Combínalo con `issue_date_gte` para definir un rango de fechas.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-01-31"
          },
          {
            "name": "reception_date_from",
            "in": "query",
            "description": "Fecha de recepción mínima (inclusive) en formato `YYYY-MM-DD`. Filtra documentos recibidos cuya fecha de recepción en el libro del SII sea igual o posterior a esta fecha. Solo aplica a documentos que están en el libro de compras del SII (`document_type=received`).",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-01-01"
          },
          {
            "name": "reception_date_to",
            "in": "query",
            "description": "Fecha de recepción máxima (inclusive) en formato `YYYY-MM-DD`. Filtra documentos recibidos cuya fecha de recepción en el libro del SII sea igual o anterior a esta fecha. Solo aplica a documentos que están en el libro de compras del SII (`document_type=received`). Combínalo con `reception_date_from` para definir un rango.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-01-31"
          },
          {
            "name": "page",
            "in": "query",
            "description": "Página actual, parte de la paginación estándar. Por defecto: 1. La respuesta incluye `count` (total), `next`, `previous` (URLs de navegación) y `results` (arreglo de documentos con información de emisor, receptor, montos, estado, PDF y referencias).",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Tamaño de página (máx. 100). Por defecto: 20.",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "include_trace_events",
            "in": "query",
            "description": "Si es `true`, cada documento incluye el array completo `traces` con sus `events` (eventos de la traza del SII: ACD, ERM, RCD, etc.). Por defecto la lista no incluye la traza detallada para no inflar la respuesta. Úsalo solo cuando necesites trazabilidad detallada — el endpoint de detalle (`GET /documents/{document_id}`) ya retorna estos eventos siempre.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "json_param__{key}",
            "in": "query",
            "description": "Filtra por cualquier key del objeto `json_param` que guardaste al crear el documento (ver `json_param` en el endpoint de creación). Reemplaza `{key}` por el nombre real de tu campo, ej. `json_param__external_order_id=PED-123`. Coincidencia exacta (no búsqueda parcial); puedes repetir el parámetro con distintas keys en la misma request y se combinan con AND. La key solo acepta `[a-zA-Z0-9_]` (máx. 64 caracteres) — otro caracter devuelve 400. El valor de la query siempre se compara como string, así que solo sirve para keys cuyo valor en `json_param` también sea un string; valores booleanos o numéricos no son filtrables por esta vía todavía.",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "PED-123"
          },
          {
            "name": "include_book_metadata",
            "in": "query",
            "description": "Si es `true`, cada documento incluye el objeto `book_metadata` con todos los datos del Registro de Compras y Ventas (RCV) del SII: montos según el libro (`net_amount`, `vat_amount`, `total_amount`, `exempt_amount`), IVA no recuperable/uso común/retenido, fechas de recepción y acuse, flags `in_sii_compra_book`/`in_sii_venta_book` y los períodos de carga `compra_loading_period`/`venta_loading_period` (YYYYMM). Es `null` si el documento aún no aparece en el RCV. Para reconstruir el **libro de compras** de un período usa `document_type=received` y filtra por `in_sii_compra_book=true` y `compra_loading_period`; para el **libro de ventas** usa `document_type=issued` con `in_sii_venta_book=true` y `venta_loading_period` (el período de carga del RCV puede diferir de la fecha de emisión en documentos de fin de mes).",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de documentos obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a esta entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Entidad no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/folio-queries/": {
      "post": {
        "operationId": "createFolioQuery_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Pedir una lectura de folios al SII",
        "description": "Crea una consulta de folios contra el SII. Es un **recurso asíncrono**: responde 201 con `status: \"pending\"` y lee en segundo plano.\n\n**Consultar no consume folios**: el trámite se queda en el paso 1 del portal, que no reserva ningún rango. Por eso no lleva `Idempotency-Key` — repetirla no cuesta nada irreversible.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "master_entity_id",
                  "dte_type"
                ],
                "properties": {
                  "master_entity_id": {
                    "type": "string",
                    "description": "ID de la entidad. El public ID de la entidad (`ment_...`).",
                    "example": "ment_4829301923847"
                  },
                  "dte_type": {
                    "type": "integer",
                    "description": "Tipo de DTE a consultar.",
                    "example": 33
                  },
                  "sii_environment": {
                    "type": "string",
                    "enum": [
                      "production",
                      "certification"
                    ],
                    "default": "production",
                    "description": "Ambiente del SII contra el que se hace la operación. `production` (palena) entrega folios REALES, que no se devuelven; `certification` (maullin) entrega folios de prueba, que NO sirven para emitir. Si se omite, producción. Un valor distinto de los dos se rechaza con 422 en vez de asumir un default.",
                    "example": "certification"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Consulta creada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioQuery"
                }
              }
            }
          },
          "400": {
            "description": "Tipo de documento inválido."
          },
          "403": {
            "description": "La entidad no pertenece al cliente."
          },
          "429": {
            "description": "Límite horario de consultas agotado (10 por hora, por empresa). Se cuenta aparte de la cuota de timbraje.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioQuotaExceeded"
                }
              }
            }
          },
          "422": {
            "description": "El ambiente pedido no existe o no está habilitado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "error_code": {
                      "type": "string",
                      "enum": [
                        "invalid_environment",
                        "environment_not_allowed",
                        "certification_not_enabled"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listFolioQueries_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar consultas de folios",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID de la entidad. El public ID de la entidad (`ment_...`).",
            "example": "ment_4829301923847"
          },
          {
            "name": "dte_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Filtra por tipo de documento."
          },
          {
            "name": "sii_environment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "production",
                "certification"
              ],
              "default": "production"
            },
            "description": "Ambiente del SII. Si se omite, producción: los folios de certificación son un stock distinto y mostrarlos como propios sería peor que no mostrar nada."
          }
        ],
        "responses": {
          "200": {
            "description": "Consultas de la entidad.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FolioQuery"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/folio-queries/{id}/": {
      "get": {
        "operationId": "getFolioQuery_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Resultado de una consulta de folios",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado y resultado de la consulta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioQuery"
                }
              }
            }
          },
          "403": {
            "description": "La consulta es de otra entidad."
          },
          "404": {
            "description": "Consulta no encontrada."
          }
        }
      }
    },
    "/folio-requests/{id}/": {
      "get": {
        "operationId": "getFolioRequest_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Consultar un pedido y retirar el CAF",
        "description": "Estado del pedido de timbraje. Cuando `status` es `completed`, la respuesta incluye el **CAF en XML** (`caf_xml`) y el rango de folios autorizado.\n\nEl CAF contiene la llave privada con la que se firman tus DTE: trátalo como un secreto. Cada entrega queda registrada.\n\nEstados posibles:\n\n| `status` | Qué significa |\n|---|---|\n| `pending` | Registrado, aún no empieza |\n| `processing` | El trámite está corriendo en el SII |\n| `completed` | Listo: `caf_xml` trae tus folios |\n| `failed` | El SII no autorizó folios. No se consumió nada, puedes volver a pedir con otra `Idempotency-Key` |\n| `authorized_without_caf` | El SII autorizó el rango pero no entregó el archivo. **Esos folios ya salieron de tu stock**: no vuelvas a pedir el mismo rango, estamos recuperando el CAF. `folio_start` y `folio_end` indican cuál |",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID del pedido de timbraje.",
            "example": 8821
          }
        ],
        "responses": {
          "200": {
            "description": "Pedido encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioRequest"
                },
                "example": {
                  "id": "fir_8d4a2f7c1e9b5",
                  "dte_type": 33,
                  "status": "completed",
                  "requested_quantity": 50,
                  "granted_quantity": 50,
                  "folio_start": 539,
                  "folio_end": 588,
                  "caf_xml": "<AUTORIZACION><CAF version=\"1.0\">…</CAF></AUTORIZACION>",
                  "idempotency_key": "pedido-facturas-2026-08-27-01",
                  "error": "",
                  "created_at": "2026-08-27T14:30:00Z",
                  "completed_at": "2026-08-27T14:32:11Z"
                }
              }
            }
          },
          "403": {
            "description": "El pedido pertenece a otra entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Pedido no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Pedido no encontrado."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/folio-requests/": {
      "post": {
        "operationId": "createFolioRequest_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Solicitar timbraje de folios",
        "description": "Pide folios al SII para tu empresa y te devuelve el **CAF** en XML para que emitas con tu propio facturador.\n\nEs un **recurso asíncrono**: el trámite ante el SII son cuatro pasos y puede tardar minutos, así que la API registra el pedido, responde **201** con `status: \"pending\"` y el timbraje corre en segundo plano. Consulta el pedido con `GET /folio-requests/{id}` o suscríbete al webhook `folio_request.completed`.\n\n**La cabecera `Idempotency-Key` es obligatoria.** Un folio timbrado no se puede devolver: si repites la llamada con la misma clave te devolvemos el pedido original (200) en vez de timbrar de nuevo. Usa una clave distinta por cada pedido real.\n\nRequisitos: tu empresa debe tener cargado en Tupana un certificado digital vigente, y la persona del certificado debe estar autorizada ante el SII para timbrar por la empresa.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clave única del pedido. Repetirla devuelve el pedido original sin timbrar de nuevo.",
            "example": "pedido-facturas-2026-08-27-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "master_entity_id",
                  "dte_type",
                  "quantity"
                ],
                "properties": {
                  "master_entity_id": {
                    "type": "string",
                    "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
                    "example": "ment_4829301923847"
                  },
                  "dte_type": {
                    "type": "integer",
                    "description": "Código del tipo de documento a timbrar.",
                    "enum": [
                      33,
                      34,
                      39,
                      41,
                      43,
                      46,
                      52,
                      56,
                      61,
                      110,
                      111,
                      112
                    ],
                    "example": 33
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000,
                    "description": "Folios a pedir. El SII acota cada solicitud con su propio máximo autorizado, que sube con el uso: es normal recibir menos de los pedidos. Consulta el tope vigente en `GET /folios`.",
                    "example": 50
                  },
                  "sii_environment": {
                    "type": "string",
                    "enum": [
                      "production",
                      "certification"
                    ],
                    "default": "production",
                    "description": "Ambiente del SII contra el que se hace la operación. `production` (palena) entrega folios REALES, que no se devuelven; `certification` (maullin) entrega folios de prueba, que NO sirven para emitir. Si se omite, producción. Un valor distinto de los dos se rechaza con 422 en vez de asumir un default.",
                    "example": "certification"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ya existía un pedido con esa `Idempotency-Key`: se devuelve el original, sin timbrar de nuevo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioRequest"
                }
              }
            }
          },
          "201": {
            "description": "Pedido registrado; el timbraje corre en segundo plano",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioRequest"
                },
                "example": {
                  "id": "fir_8d4a2f7c1e9b5",
                  "dte_type": 33,
                  "status": "pending",
                  "requested_quantity": 50,
                  "granted_quantity": null,
                  "folio_start": null,
                  "folio_end": null,
                  "caf_xml": null,
                  "idempotency_key": "pedido-facturas-2026-08-27-01",
                  "error": "",
                  "created_at": "2026-08-27T14:30:00Z",
                  "completed_at": null,
                  "sii_environment": "production",
                  "error_code": ""
                }
              }
            }
          },
          "400": {
            "description": "Falta la cabecera `Idempotency-Key`, el tipo de DTE no es timbrable o la cantidad está fuera de rango",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "La cabecera Idempotency-Key es obligatoria: sin ella un reintento timbraría folios de nuevo."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad indicada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Ya hay un timbraje de ese tipo de documento en curso para la empresa. Espera a que termine: dos trámites simultáneos sobre el mismo tipo pueden consumir rangos de más.. También cuando la `Idempotency-Key` ya se usó en el otro ambiente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "error_code": {
                      "type": "string",
                      "enum": [
                        "idempotency_environment_conflict"
                      ]
                    }
                  }
                },
                "example": {
                  "error": "La clave de idempotencia 'pedido-01' ya se usó en production y ahora se pide en certification. Usa una clave distinta por ambiente.",
                  "error_code": "idempotency_environment_conflict"
                }
              }
            }
          },
          "429": {
            "description": "Cuota de timbrajes agotada (3 por hora o 20 por mes, por empresa). El cuerpo dice cuál se agotó y cuándo se libera.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolioQuotaExceeded"
                }
              }
            }
          },
          "422": {
            "description": "El ambiente pedido no existe, no está habilitado, o la empresa no está postulada en certificación",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "error_code": {
                      "type": "string",
                      "enum": [
                        "invalid_environment",
                        "environment_not_allowed",
                        "certification_not_enabled"
                      ]
                    }
                  }
                },
                "example": {
                  "error": "Ambiente 'staging' desconocido. Valores válidos: certification, production.",
                  "error_code": "invalid_environment"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listFolioRequests_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar pedidos de timbraje",
        "description": "Pedidos de timbraje de la entidad, del más reciente al más antiguo.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID de la entidad maestra (public ID `ment_...`).",
            "example": "ment_4829301923847"
          },
          {
            "name": "dte_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Filtra por tipo de documento.",
            "example": 33
          },
          {
            "name": "sii_environment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "production",
                "certification"
              ]
            },
            "description": "Filtra por ambiente. Si se omite, se listan los de los DOS ambientes: es lo que necesita un cliente que está migrando de uno a otro."
          }
        ],
        "responses": {
          "200": {
            "description": "Listado de pedidos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FolioRequest"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/folios/": {
      "get": {
        "operationId": "listFolioAvailability_v2",
        "tags": [
          "Folios"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Folios disponibles y timbrajes históricos",
        "description": "Última lectura conocida del estado de tus folios en el SII: cuántos tienes timbrados y sin emitir (`available`), cuántos te autoriza el SII por solicitud (`max_per_request`) y los rangos que te timbraron antes (`timbrajes`).\n\nEl dato vive en el SII y solo se conoce consultándolo, así que este endpoint responde con la **última foto guardada** y su fecha (`as_of`) — no bloquea. Para forzar una relectura usa `POST /folios/refresh`.\n\nSi la entidad nunca fue consultada, `results` viene vacío. Vacío significa *no sabemos*, no *cero folios*.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID de la entidad maestra (public ID `ment_...`).",
            "example": "ment_4829301923847"
          },
          {
            "name": "dte_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Filtra por tipo de documento.",
            "example": 33
          },
          {
            "name": "sii_environment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "production",
                "certification"
              ],
              "default": "production"
            },
            "description": "Ambiente del SII. Si se omite, producción: los folios de certificación son un stock distinto y mostrarlos como propios sería peor que no mostrar nada."
          }
        ],
        "responses": {
          "200": {
            "description": "Última foto conocida por tipo de documento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FolioAvailability"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "dte_type": 33,
                      "available": 120,
                      "max_per_request": 50,
                      "last_timbraje": "2026-08-19",
                      "timbrajes": [
                        {
                          "authorization_date": "2026-08-19",
                          "quantity": 50,
                          "folio_start": 539,
                          "folio_end": 588,
                          "consistent": true
                        }
                      ],
                      "as_of": "2026-08-27T14:05:00Z"
                    }
                  ],
                  "meta": {
                    "page": null,
                    "page_size": null,
                    "total": 1,
                    "total_pages": null
                  },
                  "links": {
                    "next": null,
                    "prev": null
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad indicada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/honorary/authorized-users/": {
      "get": {
        "summary": "Listar usuarios autorizados",
        "description": "Obtiene la lista de usuarios autorizados para emitir boletas de honorarios, leída desde un caché local. Nunca consulta el SII en el momento del request — para refrescarla contra el SII, usa POST /honorary/master-entities/{master_entity_id}/authorized-users/sync/. El master_entity_id se proporciona como query parameter.",
        "tags": [
          "Honorary"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "ID de la entidad maestra"
            },
            "description": "ID de la entidad para la cual se consultan los autorizados. Debe proporcionarse como query parameter."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de usuarios autorizados obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "authorized_users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rut": {
                            "type": "string",
                            "description": "RUT del usuario con formato de puntos y guión",
                            "example": "12.345.678-9"
                          },
                          "nombre": {
                            "type": "string",
                            "description": "Nombre completo del usuario autorizado",
                            "example": "MARIA JOSEFA GONZALEZ LOPEZ"
                          },
                          "enrolled": {
                            "type": "boolean",
                            "description": "Si el usuario ya está enrolado en el sistema",
                            "example": false
                          }
                        },
                        "required": [
                          "rut",
                          "nombre",
                          "enrolled"
                        ]
                      }
                    },
                    "last_sync_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "queued",
                        "syncing",
                        "done",
                        "error",
                        null
                      ],
                      "description": "Estado del último intento de sincronización con el SII. null si esta entidad nunca fue sincronizada.",
                      "example": "done"
                    },
                    "last_sync_error": {
                      "type": "string",
                      "description": "Mensaje de error del último intento, solo presente si last_sync_status es 'error'",
                      "example": ""
                    },
                    "last_synced_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Fecha y hora (ISO 8601) en que terminó la última sincronización exitosa o fallida. null si nunca terminó ninguna (incluye el caso de una sincronización todavía en curso, cuando aún no hay ninguna completada).",
                      "example": "2026-07-22T15:40:12.123456+00:00"
                    }
                  },
                  "required": [
                    "authorized_users"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Parámetros inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Se requiere el parámetro master_entity_id"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Usuario sin permisos para acceder a la entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entidad no encontrada o sin credenciales",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "No se encontró una credencial válida para la entidad"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error al obtener usuarios autorizadores"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Enrolar usuario autorizado",
        "description": "Enrola un usuario autorizado del SII para emitir boletas de honorarios. El RUT se valida contra el caché local (poblado por POST .../authorized-users/sync/), no contra el SII en vivo — sincroniza primero si la entidad nunca fue sincronizada. El master_entity_id y rut se proporcionan en el body o query parameters. Para desenrolar, usa el endpoint de desenrolar.",
        "tags": [
          "Honorary"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "ID de la entidad emisora"
            },
            "description": "ID de la entidad emisora. Puede proporcionarse en query parameter o en el body."
          },
          {
            "name": "rut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "RUT del usuario autorizado"
            },
            "description": "RUT del usuario a gestionar. Puede proporcionarse en query parameter o en el body."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "master_entity_id": {
                    "type": "integer",
                    "description": "ID de la entidad emisora (requerido si no se proporciona en query parameter)",
                    "example": 1
                  },
                  "rut": {
                    "type": "string",
                    "description": "RUT del usuario autorizado (requerido si no se proporciona en query parameter)",
                    "example": "12.345.678-9"
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "enroll",
                      "unenroll"
                    ],
                    "description": "Acción a realizar. Por defecto 'enroll'",
                    "default": "enroll",
                    "example": "enroll"
                  }
                },
                "required": [
                  "master_entity_id",
                  "rut"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operación exitosa (enrolar o desenrolar)",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Respuesta al enrolar",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "enrolled",
                            "already_enrolled"
                          ],
                          "description": "Estado del enrolamiento"
                        },
                        "message": {
                          "type": "string",
                          "description": "Mensaje descriptivo"
                        },
                        "rut": {
                          "type": "string",
                          "description": "RUT normalizado del usuario enrolado"
                        },
                        "master_entity": {
                          "type": "object",
                          "description": "Información de la entidad creada/asociada",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "ID de la entidad"
                            },
                            "name": {
                              "type": "string",
                              "description": "Nombre completo de la entidad"
                            },
                            "tax_id": {
                              "type": "string",
                              "description": "RUT de la entidad"
                            }
                          }
                        }
                      },
                      "required": [
                        "status",
                        "message",
                        "rut"
                      ]
                    },
                    {
                      "type": "object",
                      "description": "Respuesta al desenrolar",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "Siempre true para respuestas exitosas",
                          "example": true
                        },
                        "message": {
                          "type": "string",
                          "description": "Mensaje descriptivo del resultado",
                          "example": "Usuario autorizador 12345678-9 desenrolado exitosamente"
                        },
                        "rut": {
                          "type": "string",
                          "description": "RUT del usuario desenrolado",
                          "example": "12345678-9"
                        }
                      },
                      "required": [
                        "success",
                        "message",
                        "rut"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos, usuario no autorizado, o acción inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "oneOf": [
                        {
                          "example": "Se requiere el parámetro master_entity_id"
                        },
                        {
                          "example": "Se requiere el parámetro rut"
                        },
                        {
                          "example": "El RUT proporcionado no está en la lista de usuarios autorizadores"
                        },
                        {
                          "example": "Aún no se ha sincronizado la lista de usuarios autorizadores con el SII para esta entidad. Sincroniza primero e inténtalo de nuevo."
                        },
                        {
                          "example": "La acción debe ser 'enroll' o 'unenroll'"
                        },
                        {
                          "example": "El RUT proporcionado no es válido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Usuario sin permisos para acceder a la entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entidad, credencial o usuario no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "oneOf": [
                        {
                          "example": "No se encontró una credencial válida para la entidad"
                        },
                        {
                          "example": "No se encontró una entidad con el RUT asociada al usuario"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error al gestionar usuario autorizador"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/honorary/master-entities/{master_entity_id}/authorized-users/": {
      "get": {
        "summary": "Listar usuarios autorizados",
        "description": "Obtiene la lista de usuarios autorizados para emitir boletas de honorarios, leída desde un caché local. Nunca consulta el SII en el momento del request — para refrescarla contra el SII, usa POST /honorary/master-entities/{master_entity_id}/authorized-users/sync/.",
        "tags": [
          "Honorary"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "ID de la entidad maestra"
            },
            "description": "ID de la entidad para la cual se consultan los autorizados"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de usuarios autorizados obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "authorized_users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rut": {
                            "type": "string",
                            "description": "RUT del usuario con formato de puntos y guión",
                            "example": "12.345.678-9"
                          },
                          "nombre": {
                            "type": "string",
                            "description": "Nombre completo del usuario autorizado",
                            "example": "MARIA JOSEFA GONZALEZ LOPEZ"
                          },
                          "enrolled": {
                            "type": "boolean",
                            "description": "Si el usuario ya está enrolado en el sistema",
                            "example": false
                          }
                        },
                        "required": [
                          "rut",
                          "nombre",
                          "enrolled"
                        ]
                      }
                    },
                    "last_sync_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "queued",
                        "syncing",
                        "done",
                        "error",
                        null
                      ],
                      "description": "Estado del último intento de sincronización con el SII. null si esta entidad nunca fue sincronizada.",
                      "example": "done"
                    },
                    "last_sync_error": {
                      "type": "string",
                      "description": "Mensaje de error del último intento, solo presente si last_sync_status es 'error'",
                      "example": ""
                    },
                    "last_synced_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Fecha y hora (ISO 8601) en que terminó la última sincronización exitosa o fallida. null si ninguna ha terminado todavía.",
                      "example": "2026-07-22T15:40:12.123456+00:00"
                    }
                  },
                  "required": [
                    "authorized_users"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Parámetros inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Se requiere el parámetro 'master_entity_id'"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Usuario sin permisos para acceder a la entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entidad no encontrada o sin credenciales",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "No se encontró una credencial válida para la entidad"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error al obtener usuarios autorizadores"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/honorary/master-entities/{master_entity_id}/authorized-users/{rut}/": {
      "patch": {
        "summary": "Enrolar usuario autorizado",
        "description": "Enrola un usuario autorizado del SII para emitir boletas de honorarios. El RUT se valida contra el caché local (poblado por POST .../authorized-users/sync/), no contra el SII en vivo — sincroniza primero si la entidad nunca fue sincronizada. Para desenrolar, usa el endpoint de desenrolar.",
        "tags": [
          "Honorary"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "ID de la entidad emisora"
            },
            "description": "ID de la entidad emisora"
          },
          {
            "name": "rut",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "RUT del usuario autorizado"
            },
            "description": "RUT del usuario a gestionar (con o sin formato)"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "enroll",
                      "unenroll"
                    ],
                    "description": "Acción a realizar. Por defecto 'enroll'",
                    "default": "enroll",
                    "example": "enroll"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operación exitosa (enrolar o desenrolar)",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Respuesta al enrolar",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "enrolled",
                            "already_enrolled"
                          ],
                          "description": "Estado del enrolamiento"
                        },
                        "message": {
                          "type": "string",
                          "description": "Mensaje descriptivo"
                        },
                        "rut": {
                          "type": "string",
                          "description": "RUT normalizado del usuario enrolado"
                        },
                        "master_entity": {
                          "type": "object",
                          "description": "Información de la entidad creada/asociada",
                          "properties": {
                            "id": {
                              "type": "integer",
                              "description": "ID de la entidad"
                            },
                            "name": {
                              "type": "string",
                              "description": "Nombre completo de la entidad"
                            },
                            "tax_id": {
                              "type": "string",
                              "description": "RUT de la entidad"
                            }
                          }
                        }
                      },
                      "required": [
                        "status",
                        "message",
                        "rut"
                      ]
                    },
                    {
                      "type": "object",
                      "description": "Respuesta al desenrolar",
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "description": "Siempre true para respuestas exitosas",
                          "example": true
                        },
                        "message": {
                          "type": "string",
                          "description": "Mensaje descriptivo del resultado",
                          "example": "Usuario autorizador 12345678-9 desenrolado exitosamente"
                        },
                        "rut": {
                          "type": "string",
                          "description": "RUT del usuario desenrolado",
                          "example": "12345678-9"
                        }
                      },
                      "required": [
                        "success",
                        "message",
                        "rut"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos, usuario no autorizado, o acción inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "oneOf": [
                        {
                          "example": "El RUT proporcionado no está en la lista de usuarios autorizadores"
                        },
                        {
                          "example": "Aún no se ha sincronizado la lista de usuarios autorizadores con el SII para esta entidad. Sincroniza primero e inténtalo de nuevo."
                        },
                        {
                          "example": "La acción debe ser 'enroll' o 'unenroll'"
                        },
                        {
                          "example": "El RUT proporcionado no es válido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Usuario sin permisos para acceder a la entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entidad, credencial o usuario no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "oneOf": [
                        {
                          "example": "No se encontró una credencial válida para la entidad"
                        },
                        {
                          "example": "No se encontró una entidad con el RUT asociada al usuario"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Error al gestionar usuario autorizador"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/honorary/master-entities/{master_entity_id}/authorized-users/sync/": {
      "post": {
        "summary": "Sincronizar usuarios autorizados con el SII",
        "description": "Encola de forma asíncrona (no bloquea la respuesta) una consulta al SII para refrescar el caché local de usuarios autorizados de la entidad. Responde de inmediato con un job_id. El caché nunca queda vacío ni se corrompe por un sync fallido: solo un sync exitoso puede actualizar o desactivar usuarios (nunca los borra). Para saber cuándo terminó, haz polling de GET /honorary/master-entities/{master_entity_id}/authorized-users/ hasta que last_sync_status sea 'done' o 'error' — el canal WebSocket que expone el avance en tiempo real solo acepta autenticación de sesión (JWT), no API key.",
        "tags": [
          "Honorary"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "ID de la entidad emisora"
            },
            "description": "ID de la entidad emisora a sincronizar"
          }
        ],
        "responses": {
          "202": {
            "description": "Sincronización encolada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "integer",
                      "description": "ID del job de sincronización, útil para trazabilidad interna",
                      "example": 123
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued"
                      ],
                      "example": "queued"
                    },
                    "channel_key": {
                      "type": "string",
                      "description": "Canal WebSocket interno (solo JWT) donde se publica el avance",
                      "example": "honorary-authorized-users-sync-456"
                    }
                  },
                  "required": [
                    "job_id",
                    "status",
                    "channel_key"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Sin permisos para acceder a la entidad, o API key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Usuario sin permisos para acceder a la entidad"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entidad no encontrada o sin acceso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "No encontrado"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/master-entities/": {
      "get": {
        "summary": "Buscar entidad por RUT",
        "description": "Busca una entidad maestra específica por su RUT. Requiere autenticación por API Key.\n\n**Permisos requeridos:** Este endpoint actualmente no requiere permisos específicos (`AllowAny`), pero requiere autenticación válida por API Key.\n\n**Respuesta:** Retorna información completa de la entidad incluyendo direcciones y actividades económicas. Si la entidad no existe en la base de datos, el sistema intentará buscarla y crearla automáticamente usando el scraper del SII.",
        "parameters": [
          {
            "name": "rut",
            "in": "query",
            "description": "RUT del cliente a consultar (formato: 76543210-1, sin puntos)",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{7,8}-[0-9K]$",
              "example": "76543210-1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Entidad encontrada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MasterEntity"
                },
                "example": {
                  "id": "ment_4829301923847",
                  "opaque_id": "ment_4829301923847",
                  "tax_id": "76.798.398-0",
                  "name": "SUPLO SPA",
                  "email": "contacto@suplo.cl",
                  "addresses": [
                    {
                      "id": "addr_0a1b2c3d4e5f6",
                      "address": "AV TAJAMAR 183 OF 401   OFIC",
                      "district": {
                        "id": "dist_1f2e3d4c5b6a7",
                        "name": "LAS CONDES",
                        "city": {
                          "id": "city_7a6b5c4d3e2f1",
                          "name": "SANTIAGO"
                        }
                      },
                      "sii_branch_code": null,
                      "phone": null
                    }
                  ],
                  "activities": [
                    {
                      "id": "acti_3c2b1a0f9e8d7",
                      "code": "620900",
                      "name": "OTRAS ACTIVIDADES DE TECNOLOGIA DE LA IN"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "API Key inválida o sin autenticación. Aunque este endpoint no requiere permisos específicos, requiere una API Key válida.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "API Key inválida o faltante"
                }
              }
            }
          },
          "400": {
            "description": "Parámetro 'rut' faltante o formato inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "API Key inválida o faltante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Entidad no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error interno del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/scheduled-documents/{id}/": {
      "patch": {
        "operationId": "updateScheduledDocument_v2",
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Actualizar documento programado",
        "description": "Actualiza parcialmente un documento programado existente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID del documento programado",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 789
            }
          },
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 123
            }
          }
        ],
        "requestBody": {
          "description": "Campos a actualizar del documento programado",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduledDocumentUpdate"
              },
              "example": {
                "status": "inactive",
                "amount": 120000,
                "currency_day": 15,
                "references": [
                  {
                    "dte_type_code": "33",
                    "reference_folio": "100",
                    "reference_date": "2024-01-15",
                    "reference_reason": "ANULA DOCUMENTO DE LA REFERENCIA"
                  }
                ],
                "details": [
                  {
                    "item_name": "Servicio actualizado",
                    "item_description": "Descripción del servicio",
                    "quantity": 1,
                    "unit_price": 120000
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Documento programado actualizado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledDocument"
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Documento programado no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Obtener documento programado",
        "description": "Obtiene los detalles de un documento programado específico.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID del documento programado",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 789
            }
          },
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 123
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Documento programado obtenido exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledDocument"
                }
              }
            }
          },
          "404": {
            "description": "Documento programado no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Eliminar documento programado",
        "description": "Elimina un documento programado existente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID del documento programado",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 789
            }
          },
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 123
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Documento programado eliminado exitosamente"
          },
          "404": {
            "description": "Documento programado no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/scheduled-documents/": {
      "post": {
        "operationId": "createScheduledDocument_v2",
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Crear documento programado",
        "description": "Crea un nuevo documento programado que se ejecutará automáticamente según la frecuencia especificada.",
        "requestBody": {
          "description": "Datos del documento programado a crear",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduledDocumentCreate"
              },
              "example": {
                "sender": 123,
                "dte_type": "33",
                "receiver_tax_id": "76111111-1",
                "frequency": "monthly",
                "day_of_month": 10,
                "currency": "CLP",
                "currency_day": 10,
                "status": "active",
                "references": [
                  {
                    "dte_type_code": "33",
                    "reference_folio": "100",
                    "reference_date": "2024-01-15",
                    "reference_reason": "ANULA DOCUMENTO DE LA REFERENCIA"
                  }
                ],
                "details": [
                  {
                    "item_name": "Servicio mensual de consultoría",
                    "item_description": "Asistencia contable mensual",
                    "quantity": 1,
                    "unit_price": 150000
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Documento programado creado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledDocument"
                },
                "example": {
                  "id": "scdo_6f1d8b3a9e2c7",
                  "sender": {
                    "id": "ment_4829301923847",
                    "name": "Empresa Ejemplo SpA",
                    "rut": "76543210-1"
                  },
                  "receiver": {
                    "id": "ment_4829301923847",
                    "name": "Cliente ABC Ltda",
                    "rut": "12345678-9"
                  },
                  "dte_type": {
                    "id": "dtty_4d5e6f7a8b9c0",
                    "code": "33",
                    "description": "Factura Electrónica"
                  },
                  "frequency": "monthly",
                  "frequency_display": "Mensual",
                  "day_of_month": 10,
                  "day_of_week": null,
                  "next_execution": "2024-03-10T10:00:00Z",
                  "status": "active",
                  "status_display": "Activo",
                  "amount": 150000,
                  "currency": "CLP",
                  "currency_day": 10,
                  "completed_occurrences": 0,
                  "max_occurrences": null,
                  "references": [
                    {
                      "id": "sdr_9e8d7c6b5a4f3",
                      "dte_type_code": "33",
                      "reference_folio": "100",
                      "reference_date": "2024-01-15",
                      "reference_reason": "ANULA DOCUMENTO DE LA REFERENCIA"
                    }
                  ],
                  "details": [
                    {
                      "id": "scdoc_2a3b4c5d6e7f8",
                      "item_name": "Servicio mensual de consultoría",
                      "item_description": "Asistencia contable mensual",
                      "quantity": 1,
                      "unit_price": 150000
                    }
                  ],
                  "created_at": "2024-02-05T12:15:00Z",
                  "updated_at": "2024-02-05T12:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error de validación en el SII",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar documentos programados",
        "description": "Obtiene una lista paginada de documentos programados de una entidad específica. Los documentos programados son plantillas que se ejecutan automáticamente según una frecuencia definida.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 123
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filtrar por estado del documento programado",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "inactive",
                "completed"
              ],
              "example": "active"
            }
          },
          {
            "name": "frequency",
            "in": "query",
            "description": "Filtrar por frecuencia de ejecución",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "daily",
                "weekly",
                "monthly",
                "quarterly"
              ],
              "example": "monthly"
            }
          },
          {
            "name": "dte_type",
            "in": "query",
            "description": "Filtrar por tipo de DTE",
            "required": false,
            "schema": {
              "type": "string",
              "example": "33"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Número de página para paginación",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "example": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Número de elementos por página",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100,
              "example": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de documentos programados obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledDocumentListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Parámetros inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/scheduled-documents/{id}/preview/": {
      "get": {
        "tags": [
          "Documentos Programados"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Preview de documento programado guardado",
        "description": "Genera un preview en PDF del próximo documento que se emitirá para un documento programado ya guardado.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID del documento programado",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 789
            }
          },
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 123
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preview generado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pdf_base64": {
                      "type": "string",
                      "description": "PDF del documento en formato base64",
                      "example": "JVBERi0xLjQKMSAwIG9iago8PC9UeXBlIC9DYXRhbG9n..."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Documento programado no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error generando el preview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autorizado - API Key inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Prohibido - Sin acceso a la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sync-requests/": {
      "get": {
        "operationId": "listSyncRequests_v2",
        "tags": [
          "Sincronización"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar solicitudes de sincronización recientes",
        "description": "Lista las solicitudes de sincronización de una entidad creadas en las últimas N horas (por defecto 24), ordenadas de la más nueva a la más antigua. Paginación simple con `page` y `page_size`.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
            "schema": {
              "type": "string",
              "example": "ment_4829301923847"
            }
          },
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "Ventana hacia atrás, en horas, sobre la fecha de creación. Por defecto 24.",
            "schema": {
              "type": "integer",
              "default": 24,
              "example": 72
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página a consultar (parte en 1).",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "Tamaño de página. Por defecto 50, máximo 200.",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de solicitudes de sincronización de la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SyncRequest"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "syre_5b6c7d8e9f0a1",
                      "master_entity_id": "ment_4829301923847",
                      "requested_types": [
                        "ISSUED_DOCS",
                        "RECEIVED_DOCS"
                      ],
                      "status": "completed",
                      "webhook_url": "",
                      "results": {
                        "ISSUED_DOCS": {
                          "success": true,
                          "new_documents": 3
                        },
                        "RECEIVED_DOCS": {
                          "success": true,
                          "new_documents": 0
                        }
                      },
                      "completed_at": "2026-07-20T14:34:12Z",
                      "created_at": "2026-07-20T14:30:00Z"
                    },
                    {
                      "id": "syre_5b6c7d8e9f0a1",
                      "master_entity_id": "ment_4829301923847",
                      "requested_types": [],
                      "status": "processing",
                      "webhook_url": "https://miapp.cl/webhooks/tupana-sync",
                      "results": {},
                      "completed_at": null,
                      "created_at": "2026-07-20T11:02:44Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "page_size": 50,
                    "total": 2,
                    "total_pages": null
                  },
                  "links": {
                    "next": null,
                    "prev": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "master_entity_id faltante o inválido, o hours/page/page_size no son enteros",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "hours debe ser un entero."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad consultada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createSyncRequest_v2",
        "tags": [
          "Sincronización"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Crear solicitud de sincronización a demanda",
        "description": "Crea una solicitud de sincronización a demanda para una entidad. Es un **recurso asíncrono**: la API crea el objeto, responde 201 de inmediato con `status: \"pending\"` y el scrape corre en segundo plano — la llamada nunca bloquea esperando al SII. Luego puedes hacer polling con `GET /sync-requests/{id}` o registrar un `webhook_url` para que te avisemos al terminar.\n\nDisponible **solo para entidades en el plan de 24 horas**. Si la entidad ya está en un plan de 12 h o 3 h, responde 400: su cartera ya se sincroniza sola con mayor frecuencia y no necesita solicitudes a demanda.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "master_entity_id"
                ],
                "properties": {
                  "master_entity_id": {
                    "type": "string",
                    "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
                    "example": "ment_4829301923847"
                  },
                  "scrape_types": {
                    "type": "array",
                    "description": "Tipos de scrape a ejecutar. Si se omite o va vacío, se sincronizan todos los tipos habilitados para la entidad.",
                    "items": {
                      "type": "string",
                      "enum": [
                        "ISSUED_DOCS",
                        "RECEIVED_DOCS",
                        "RECEIVED_HONORARY_BILLS",
                        "THIRD_PARTY_HONORARY",
                        "EMITTED_HONORARY_BILLS",
                        "PURCHASE_BOOK",
                        "SALE_BOOK",
                        "BOOK_SUMMARY"
                      ]
                    },
                    "example": [
                      "ISSUED_DOCS",
                      "RECEIVED_DOCS"
                    ]
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL opcional. Al completarse la solicitud hacemos un POST (best effort, timeout 5 s) con el payload `{id, status, results}`.",
                    "example": "https://miapp.cl/webhooks/tupana-sync"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Solicitud creada; el scrape corre en segundo plano",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncRequest"
                },
                "example": {
                  "id": "syre_5b6c7d8e9f0a1",
                  "master_entity_id": "ment_4829301923847",
                  "requested_types": [
                    "ISSUED_DOCS",
                    "RECEIVED_DOCS"
                  ],
                  "status": "pending",
                  "webhook_url": "https://miapp.cl/webhooks/tupana-sync",
                  "results": {},
                  "completed_at": null,
                  "created_at": "2026-07-20T14:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Body inválido (master_entity_id faltante, scrape_type desconocido) o la entidad está en un plan de 12 h / 3 h (la sincronización a demanda es solo para el plan de 24 horas)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "La actualización a demanda está disponible solo para el plan de 24 horas; tu plan ya sincroniza cada 12 horas."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad indicada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sync-requests/{id}/": {
      "get": {
        "operationId": "getSyncRequest_v2",
        "tags": [
          "Sincronización"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Detalle de una solicitud de sincronización",
        "description": "Devuelve el estado actual de una solicitud de sincronización. Úsalo para hacer polling después del `POST /sync-requests`: cuando `status` pase a `completed` (o `failed`), el campo `results` trae el resultado por cada tipo de scrape ejecutado.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de sincronización (campo `id` de la respuesta del POST).",
            "schema": {
              "type": "integer",
              "example": 1042
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Detalle de la solicitud, con resultados por tipo si ya terminó",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncRequest"
                },
                "example": {
                  "id": "syre_5b6c7d8e9f0a1",
                  "master_entity_id": "ment_4829301923847",
                  "requested_types": [
                    "ISSUED_DOCS",
                    "RECEIVED_DOCS"
                  ],
                  "status": "completed",
                  "webhook_url": "https://miapp.cl/webhooks/tupana-sync",
                  "results": {
                    "ISSUED_DOCS": {
                      "success": true,
                      "new_documents": 3
                    },
                    "RECEIVED_DOCS": {
                      "success": true,
                      "new_documents": 0
                    }
                  },
                  "completed_at": "2026-07-20T14:34:12Z",
                  "created_at": "2026-07-20T14:30:00Z"
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad dueña de la solicitud",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "La solicitud no existe",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No encontrado."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sync-status/": {
      "get": {
        "operationId": "getSyncStatus_v2",
        "tags": [
          "Sincronización"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Estado de sincronización de una entidad",
        "description": "Devuelve la frecuencia de sincronización contratada para la entidad (`sync_frequency_hours`: 24, 12 o 3) y la última actualización por tipo de scrape. Cada fila de `types` indica cuándo fue la última carga exitosa (`last_success_at`) y el estado de la última ejecución (`last_status`). Solo aparecen los tipos que se han sincronizado al menos una vez para la entidad.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
            "schema": {
              "type": "string",
              "example": "ment_4829301923847"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado de sincronización de la entidad",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "master_entity_id": {
                      "type": "integer",
                      "description": "ID entero de la entidad",
                      "example": 48213
                    },
                    "sync_frequency_hours": {
                      "type": "integer",
                      "enum": [
                        24,
                        12,
                        3
                      ],
                      "description": "Frecuencia de sincronización contratada, en horas. 24 es el plan por defecto; 12 y 3 (casi tiempo real) son planes de mayor frecuencia.",
                      "example": 24
                    },
                    "types": {
                      "type": "array",
                      "description": "Última actualización por tipo de scrape",
                      "items": {
                        "$ref": "#/components/schemas/SyncStatusType"
                      }
                    }
                  }
                },
                "example": {
                  "master_entity_id": "ment_4829301923847",
                  "sync_frequency_hours": 24,
                  "types": [
                    {
                      "scrape_type": "ISSUED_DOCS",
                      "last_success_at": "2026-07-20T06:12:41Z",
                      "last_status": "completed"
                    },
                    {
                      "scrape_type": "RECEIVED_DOCS",
                      "last_success_at": "2026-07-20T06:15:03Z",
                      "last_status": "completed"
                    },
                    {
                      "scrape_type": "PURCHASE_BOOK",
                      "last_success_at": "2026-07-19T06:14:10Z",
                      "last_status": "failed"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "master_entity_id faltante o inválido",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "master_entity_id es requerido."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad consultada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No tienes acceso a esta entidad."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "La entidad no existe",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "No encontrado."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/": {
      "get": {
        "operationId": "listWebhooks_v2",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar webhooks",
        "description": "Obtiene la lista de webhooks configurados para las entidades accesibles del usuario autenticado. Si se proporciona master_entity_id, filtra solo los webhooks de esa entidad.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "description": "ID de la entidad maestra para filtrar webhooks. Opcional. Si no se proporciona, retorna webhooks de todas las entidades accesibles del usuario autenticado.",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": 123
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de webhooks obtenida exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "dowe_2c9e5a1b7f3d0",
                      "url": "https://mi-sistema.com/webhook",
                      "events": [
                        "document.issued",
                        "document.delivered"
                      ],
                      "events_display": [
                        "Emitido",
                        "Entregado"
                      ],
                      "secret": "mi-clave-secreta",
                      "is_active": true,
                      "last_status_code": 200,
                      "last_sent_at": "2025-01-13T10:30:00Z",
                      "success_rate": 95.5,
                      "last_delivery": {
                        "id": "dowe_2c9e5a1b7f3d0",
                        "event": "document.issued",
                        "is_success": true,
                        "status_code": 200,
                        "sent_at": "2025-01-13T10:30:00Z",
                        "document_id": "docu_9f2a7c1b8e4d0"
                      },
                      "created_at": "2025-01-01T09:00:00Z",
                      "updated_at": "2025-01-13T10:30:00Z"
                    }
                  ],
                  "meta": {
                    "page": null,
                    "page_size": null,
                    "total": 1,
                    "total_pages": null
                  },
                  "links": {
                    "next": null,
                    "prev": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Usuario no autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Usuario sin acceso a entidades",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createWebhook_v2",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Crear webhook",
        "description": "Crea un nuevo webhook para una entidad específica del usuario autenticado.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreate"
              },
              "example": {
                "master_entity_id": "ment_4829301923847",
                "url": "https://mi-sistema.com/webhook/callback",
                "events": [
                  "document.issued",
                  "document.delivered",
                  "document.rejected"
                ],
                "secret": "mi-clave-secreta-super-segura",
                "is_active": true,
                "environment": "production",
                "api_version": 2
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook creado exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "dowe_2c9e5a1b7f3d0",
                  "url": "https://mi-sistema.com/webhook/callback",
                  "events": [
                    "document.issued",
                    "document.delivered",
                    "document.rejected"
                  ],
                  "events_display": [
                    "Emitido",
                    "Entregado",
                    "Rechazado SII"
                  ],
                  "secret": "mi-clave-secreta-super-segura",
                  "is_active": true,
                  "last_status_code": null,
                  "last_sent_at": null,
                  "success_rate": 0,
                  "last_delivery": null,
                  "created_at": "2025-01-13T11:00:00Z",
                  "updated_at": "2025-01-13T11:00:00Z",
                  "environment": "production",
                  "api_version": 2
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Usuario no autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Usuario sin acceso a entidades",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/connections/": {
      "get": {
        "operationId": "listConnections_v2",
        "summary": "Listar conexiones",
        "description": "Las empresas conectadas a tu integración. Es también el paso \"empresa emisora\" de cualquier flujo: cada conexión trae el giro, su código y la dirección, así que no necesitas guardarlos — mandas `company_id` y la API completa el emisor.",
        "tags": [
          "Conexiones"
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 2
            },
            "description": "Filtra por nombre o RUT. Mínimo 2 caracteres."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "minimum": 1,
              "maximum": 100
            },
            "description": "Conexiones por página. Se acota a 100."
          }
        ],
        "responses": {
          "200": {
            "description": "Conexiones del integrador",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "connection_id": {
                            "type": "string",
                            "example": "cred_2959001189629508554"
                          },
                          "company_id": {
                            "type": "string",
                            "example": "ment_3672486436546233854"
                          },
                          "provider": {
                            "type": "string",
                            "example": "sii"
                          },
                          "type": {
                            "type": "string",
                            "example": "tax"
                          },
                          "name": {
                            "type": "string",
                            "example": "1 A 1 ARQUITECTURA Y CONSTRUCCIÓN SPA"
                          },
                          "tax_id": {
                            "type": "string",
                            "example": "77.918.412-9"
                          },
                          "environment": {
                            "type": "string",
                            "enum": [
                              "sandbox",
                              "production"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "requires_action"
                            ],
                            "description": "`requires_action`: la clave dejó de servir y el usuario final tiene que reconectar."
                          },
                          "last_verified_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "business_activity": {
                            "type": "string",
                            "description": "Giro del emisor, tal como lo necesita el documento."
                          },
                          "activity_code": {
                            "type": "integer",
                            "nullable": true
                          },
                          "address": {
                            "type": "string"
                          },
                          "district": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Cuántas conexiones hay en total. Va aparte del largo de `data` para que un corte por `limit` nunca pase inadvertido."
                    },
                    "limit": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "La búsqueda trae menos de 2 caracteres"
          }
        }
      }
    },
    "/connections/{connection_id}/": {
      "delete": {
        "operationId": "deactivateConnection_v2",
        "summary": "Desactivar una conexión",
        "description": "Corta una conexión: deja de servir para operar y Tupana suelta la clave que guardaba. No es un borrado — la conexión sigue en el listado con `status: inactive`, que es lo que explica por qué esa empresa dejó de sincronizar. La empresa y sus documentos no se tocan. Se identifica por `connection_id` (el `cred_…` del listado), no por la empresa. Es idempotente y no tiene vuelta atrás: volver a operar esa empresa significa conectarla de nuevo con Tupana Link.",
        "tags": [
          "Conexiones"
        ],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "cred_5028174639201"
            },
            "example": "ment_3672486436546233854",
            "description": "Id de la conexión (`cred_…`), el que devuelve GET /connections/."
          }
        ],
        "responses": {
          "200": {
            "description": "Conexión terminada"
          },
          "404": {
            "description": "La empresa no está conectada a tu integración"
          }
        }
      }
    },
    "/webhooks/{webhook_id}/": {
      "get": {
        "operationId": "getWebhook_v2",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Obtener webhook",
        "description": "Detalle de un webhook de una empresa accesible con la API key. Un webhook de otra empresa responde 404.",
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "description": "public_id del webhook (`dowe_…`)",
            "schema": {
              "type": "string"
            },
            "example": "dowe_2c9e5a1b7f3d0"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "description": "No autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Webhook no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook_v2",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Actualizar webhook",
        "description": "Modifica uno o más campos del webhook. Es la forma de subir un webhook creado antes de octubre 2026 al contrato de ids públicos: `{\"api_version\": 2}`.",
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "description": "public_id del webhook (`dowe_…`)",
            "schema": {
              "type": "string"
            },
            "example": "dowe_2c9e5a1b7f3d0"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdate"
              },
              "example": {
                "api_version": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "Datos inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Webhook no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook_v2",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Eliminar webhook",
        "description": "Elimina el webhook. Las entregas ya registradas se conservan para auditoría.",
        "parameters": [
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "description": "public_id del webhook (`dowe_…`)",
            "schema": {
              "type": "string"
            },
            "example": "dowe_2c9e5a1b7f3d0"
          }
        ],
        "responses": {
          "204": {
            "description": "Webhook eliminado"
          },
          "401": {
            "description": "No autenticado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Webhook no encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/book-documents/": {
      "get": {
        "operationId": "listBookDocuments_v2",
        "tags": [
          "Libros SII"
        ],
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "summary": "Listar detalle de libro de compras/ventas SII",
        "description": "Lista, documento por documento, el Registro de Compras y Ventas (RCV) del SII de una entidad para un período tributario y una operación. Es el detalle del que `/book-summaries` entrega los totales. Cada fila trae los montos tal como los informa el SII y el desglose de impuestos del RCV. Solo devuelve datos para entidades con el scrape del libro habilitado (ver `is_enabled`); la habilitación es independiente de la del resumen.",
        "parameters": [
          {
            "name": "master_entity_id",
            "in": "query",
            "required": true,
            "description": "ID de la entidad maestra. El public ID de la entidad (`ment_...`).",
            "schema": {
              "type": "string",
              "example": "ment_4829301923847"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "description": "Período tributario a consultar, formato YYYYMM. Es el período en que el SII clasifica el documento en ese libro, que puede diferir del mes de emisión.",
            "schema": {
              "type": "string",
              "example": "202603"
            }
          },
          {
            "name": "operation",
            "in": "query",
            "required": true,
            "description": "Libro a consultar: `COMPRA` (la entidad es el receptor, libro de compras) o `VENTA` (la entidad es el emisor, libro de ventas).",
            "schema": {
              "type": "string",
              "enum": [
                "COMPRA",
                "VENTA"
              ]
            }
          },
          {
            "name": "dte_type_code",
            "in": "query",
            "required": false,
            "description": "Filtra por tipo de documento SII. Lista separada por coma, por ejemplo `33,61`.",
            "schema": {
              "type": "string",
              "example": "33,61"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Página (desde 1).",
            "schema": {
              "type": "integer",
              "example": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "Filas por página. Por defecto 25, máximo 100.",
            "schema": {
              "type": "integer",
              "example": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Filas del libro para la entidad, período y operación consultados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BookDocumentItem"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "nullable": true
                        },
                        "page_size": {
                          "type": "integer",
                          "nullable": true
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer",
                          "nullable": true
                        },
                        "is_enabled": {
                          "type": "boolean",
                          "description": "true si la entidad tiene habilitado el scrape del libro consultado (PURCHASE_BOOK para COMPRA, SALE_BOOK para VENTA). Si es false, `data` estará vacío aunque el período sea válido."
                        }
                      }
                    },
                    "links": {
                      "type": "object",
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true
                        },
                        "prev": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "master_entity_id, period u operation faltantes o inválidos, o dte_type_code mal formado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "operation is required: COMPRA or VENTA."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sin acceso a la entidad, o la API key no tiene el permiso book_summary:access",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "Access denied."
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "BookSummaryItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de la fila de resumen",
            "example": "bosu_5e8d2c9b7a1f4"
          },
          "period": {
            "type": "string",
            "description": "Período YYYYMM",
            "example": "202603"
          },
          "operation": {
            "type": "string",
            "enum": [
              "COMPRA",
              "VENTA"
            ]
          },
          "dte_type_code": {
            "type": "integer",
            "nullable": true,
            "description": "Código de tipo de documento SII (33, 34, 46, 61, etc.)"
          },
          "dte_type_name": {
            "type": "string",
            "description": "Nombre del tipo de documento"
          },
          "total_docs": {
            "type": "integer",
            "description": "Cantidad de documentos en esta línea del resumen"
          },
          "net_amount": {
            "type": "integer",
            "description": "Monto neto"
          },
          "exempt_amount": {
            "type": "integer",
            "description": "Monto exento"
          },
          "vat_amount": {
            "type": "integer",
            "description": "Monto IVA"
          },
          "total_amount": {
            "type": "integer",
            "description": "Monto total"
          },
          "scraped_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha/hora en que se obtuvo este resumen desde el SII"
          }
        }
      },
      "CessionListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de la cesión",
            "example": "doce_7c3e9a1f5b2d8"
          },
          "document_id": {
            "type": "string",
            "example": "docu_9f2a7c1b8e4d0"
          },
          "document_folio": {
            "type": "string"
          },
          "document_date_issued": {
            "type": "string",
            "format": "date"
          },
          "document_amount": {
            "type": "number"
          },
          "supplier_id": {
            "type": "string",
            "example": "ment_4829301923847"
          },
          "supplier_name": {
            "type": "string"
          },
          "supplier_rut": {
            "type": "string"
          },
          "receiver_id": {
            "type": "string",
            "nullable": true,
            "example": "ment_4829301923847"
          },
          "receiver_name": {
            "type": "string",
            "nullable": true
          },
          "receiver_rut": {
            "type": "string",
            "nullable": true
          },
          "assignee_rut": {
            "type": "string"
          },
          "assignee_business_name": {
            "type": "string"
          },
          "assignee_entity_id": {
            "type": "string",
            "nullable": true,
            "example": "ment_4829301923847"
          },
          "assignee_entity_name": {
            "type": "string",
            "nullable": true
          },
          "assignee_entity_tax_id": {
            "type": "string",
            "nullable": true
          },
          "assignment_amount": {
            "type": "number"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "rejected",
              "success"
            ]
          },
          "status_message": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "internal",
              "external"
            ],
            "description": "internal = creada en Tupana; external = registrada por fuera (SII)"
          },
          "sii_date_sent": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "aec_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DocumentStateRequest": {
        "type": "object",
        "required": [
          "event_code"
        ],
        "properties": {
          "event_code": {
            "type": "string",
            "enum": [
              "ERM",
              "ACD",
              "RCD",
              "RFT",
              "RFP",
              "PAID",
              "UNPAID",
              "ANNULLED"
            ],
            "description": "Código del evento a registrar:\n- ERM: Acuse de Recibo de Mercaderías y Servicios\n- ACD: Acepta Contenido del Documento\n- RCD: Reclama Contenido del Documento\n- RFT: Reclamo por Falta Total\n- RFP: Reclamo por Falta Parcial\n- PAID: Marcar factura emitida como pagada (genera asiento cierre CxC; solo emisor; tipos 33, 34, 39, 41)\n- UNPAID: Marcar factura emitida como no pagada (revierte asiento cierre CxC; solo emisor)\n- ANNULLED: Anular una guía de despacho (52) emitida, con motivo en reason (Res. Ex. SII N°154; solo emisor)",
            "example": "ERM"
          },
          "rejection_reason": {
            "type": "string",
            "description": "Razón del rechazo (opcional, solo para eventos de rechazo: RCD, RFT, RFP)",
            "example": "Error en el monto facturado"
          },
          "reason": {
            "type": "string",
            "maxLength": 200,
            "description": "Motivo de la anulación. Obligatorio con ANNULLED (por ejemplo, el folio de la guía que la reemplaza). Se guarda con la guía anulada y se informa en el Libro de Guías.",
            "example": "Reemplazada por guía folio 1051: cambió la cantidad de bultos"
          }
        }
      },
      "DocumentStatesResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indica si la operación fue exitosa",
            "example": true
          },
          "document_id": {
            "type": "string",
            "description": "ID del documento",
            "example": "docu_9f2a7c1b8e4d0"
          },
          "folio": {
            "type": "string",
            "description": "Folio del documento",
            "example": "123"
          },
          "states": {
            "type": "array",
            "description": "Lista de estados registrados para el documento, ordenados cronológicamente (más reciente primero)",
            "items": {
              "$ref": "#/components/schemas/DocumentState"
            }
          },
          "document": {
            "$ref": "#/components/schemas/DocumentDetail"
          }
        }
      },
      "DocumentState": {
        "type": "object",
        "properties": {
          "event_code": {
            "type": "string",
            "description": "Código del evento",
            "example": "ERM"
          },
          "event_description": {
            "type": "string",
            "description": "Descripción del evento",
            "example": "Acuse de Recibo"
          },
          "event_date": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora del evento (ISO 8601)",
            "example": "2024-01-16T10:30:00Z"
          },
          "responsable_rut": {
            "type": "integer",
            "description": "RUT del responsable del evento",
            "example": 12345678
          },
          "responsable_dv": {
            "type": "string",
            "description": "Dígito verificador del RUT del responsable",
            "example": "9"
          },
          "rejected_by_user": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "Email del usuario que registró el rechazo (solo para eventos de rechazo)",
            "example": "usuario@ejemplo.com"
          },
          "accepted_by_user": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "Email del usuario que registró la aprobación (solo para eventos de aprobación)",
            "example": "usuario@ejemplo.com"
          }
        }
      },
      "DocumentStateResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indica si la operación fue exitosa",
            "example": true
          },
          "event_registered": {
            "type": "boolean",
            "description": "Indica si el evento fue registrado exitosamente",
            "example": true
          },
          "message": {
            "type": "string",
            "description": "Mensaje descriptivo del resultado",
            "example": "Acuse de Recibo registrado. Este acuse rebajará el IVA del próximo mes."
          },
          "event_data": {
            "type": "object",
            "description": "Datos adicionales del evento registrado (proporcionados por el SII)",
            "additionalProperties": true
          },
          "document": {
            "$ref": "#/components/schemas/DocumentDetail"
          },
          "email_preview_data": {
            "type": "object",
            "description": "Datos para preview de email (solo para aprobaciones, rechazos o acuses de recibo)",
            "properties": {
              "should_open_modal": {
                "type": "boolean",
                "example": true
              },
              "document_id": {
                "type": "integer",
                "example": 12345
              },
              "action": {
                "type": "string",
                "enum": [
                  "accept",
                  "reject"
                ],
                "example": "accept"
              },
              "subject": {
                "type": "string",
                "example": "Acuse de Recibo - Factura 123"
              },
              "supplier_id": {
                "type": "integer",
                "example": 67890
              },
              "supplier_name": {
                "type": "string",
                "example": "Proveedor Ejemplo S.A."
              },
              "supplier_rut": {
                "type": "string",
                "example": "12345678-9"
              },
              "document_folio": {
                "type": "string",
                "example": "123"
              },
              "pdf_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "example": "https://api.tupana.ai/v1/documents/12345/pdf"
              },
              "rejection_reason": {
                "type": "string",
                "nullable": true,
                "example": "Error en el monto facturado"
              }
            }
          }
        }
      },
      "FolioRequest": {
        "type": "object",
        "description": "Pedido de timbraje de folios ante el SII.",
        "properties": {
          "id": {
            "type": "string",
            "example": "fir_8d4a2f7c1e9b5"
          },
          "dte_type": {
            "type": "integer",
            "description": "Tipo de documento timbrado.",
            "example": 33
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed",
              "authorized_without_caf"
            ],
            "description": "`authorized_without_caf` significa que el SII autorizó el rango y no entregó el archivo: esos folios ya salieron de tu stock.",
            "example": "completed"
          },
          "requested_quantity": {
            "type": "integer",
            "description": "Folios que pediste.",
            "example": 50
          },
          "granted_quantity": {
            "type": "integer",
            "nullable": true,
            "description": "Folios que el SII autorizó. Puede ser menor al pedido: el tope por solicitud lo pone el SII y sube con el uso.",
            "example": 50
          },
          "partially_granted": {
            "type": "boolean",
            "description": "`true` cuando el SII entregó menos folios de los que pediste. Es un desenlace normal: el tope por solicitud lo fija el SII y sube con el uso de la empresa.",
            "example": true
          },
          "sii_max_per_request": {
            "type": "integer",
            "nullable": true,
            "description": "Tope por solicitud que el SII publicó al hacer este trámite: el motivo por el que se entregó menos de lo pedido.",
            "example": 9
          },
          "folio_start": {
            "type": "integer",
            "nullable": true,
            "example": 539
          },
          "folio_end": {
            "type": "integer",
            "nullable": true,
            "example": 588
          },
          "caf_xml": {
            "type": "string",
            "nullable": true,
            "description": "CAF entregado por el SII. Contiene la llave privada con la que se firman tus DTE: trátalo como secreto. Es `null` hasta que el pedido queda `completed`.",
            "example": "<AUTORIZACION><CAF version=\"1.0\">…</CAF></AUTORIZACION>"
          },
          "idempotency_key": {
            "type": "string",
            "description": "La clave que enviaste al crear el pedido.",
            "example": "pedido-facturas-2026-08-27-01"
          },
          "error": {
            "type": "string",
            "description": "Motivo del SII cuando el pedido no terminó bien.",
            "example": ""
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-27T14:30:00Z"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-27T14:32:11Z"
          },
          "sii_environment": {
            "type": "string",
            "enum": [
              "production",
              "certification"
            ],
            "description": "Ambiente del SII en el que se hizo la operación. Un CAF de `certification` NO sirve para emitir."
          },
          "error_code": {
            "type": "string",
            "description": "Vocabulario cerrado del desenlace fallido; vacío si no hubo error. Ver la página de códigos de error.",
            "enum": [
              "",
              "certification_not_enabled",
              "missing_certificate",
              "no_folios_authorized",
              "sii_unavailable",
              "sii_unrecognized_page"
            ]
          }
        }
      },
      "FolioAvailability": {
        "type": "object",
        "description": "Foto del estado de los folios de una empresa en el SII para un tipo de documento.",
        "properties": {
          "dte_type": {
            "type": "integer",
            "example": 33
          },
          "available": {
            "type": "integer",
            "nullable": true,
            "description": "Folios timbrados y sin emitir según el SII. `null` significa que el SII no publicó el dato, no que sean cero.",
            "example": 120
          },
          "max_per_request": {
            "type": "integer",
            "nullable": true,
            "description": "Máximo de folios que el SII autoriza por solicitud en este momento. Sube con el uso.",
            "example": 50
          },
          "last_timbraje": {
            "type": "string",
            "description": "Fecha del último timbraje según el SII.",
            "example": "2026-08-19"
          },
          "timbrajes": {
            "type": "array",
            "description": "Rangos timbrados históricamente a nombre de la empresa.",
            "items": {
              "type": "object",
              "properties": {
                "authorization_date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-08-19"
                },
                "quantity": {
                  "type": "integer",
                  "example": 50
                },
                "folio_start": {
                  "type": "integer",
                  "example": 539
                },
                "folio_end": {
                  "type": "integer",
                  "example": 588
                },
                "consistent": {
                  "type": "boolean",
                  "description": "`false` cuando la fila del SII no cuadra con su propio rango y la leímos en el orden documentado.",
                  "example": true
                }
              }
            }
          },
          "as_of": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo se leyó del SII. Un número sin esta fecha no dice nada.",
            "example": "2026-08-27T14:05:00Z"
          },
          "sii_environment": {
            "type": "string",
            "enum": [
              "production",
              "certification"
            ],
            "description": "Ambiente del SII en el que se hizo la operación. Un CAF de `certification` NO sirve para emitir."
          }
        }
      },
      "FolioQuotaExceeded": {
        "type": "object",
        "description": "Cuota agotada para la empresa. Timbraje y consulta tienen cuotas separadas; las dos se cuentan por empresa, no por API key.",
        "properties": {
          "error": {
            "type": "string",
            "example": "Cuota de timbrajes agotada: 3 de 3 por hora."
          },
          "limit": {
            "type": "integer",
            "description": "Tope de la ventana que se agotó.",
            "example": 3
          },
          "window": {
            "type": "string",
            "enum": [
              "hora",
              "mes"
            ],
            "example": "hora"
          },
          "used": {
            "type": "integer",
            "description": "Timbrajes ya consumidos en esa ventana.",
            "example": 3
          },
          "resets_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo vuelve a haber cupo."
          }
        }
      },
      "FolioQuery": {
        "type": "object",
        "description": "Consulta de folios al SII. Es un recurso para que puedas seguirla: antes esto era una acción que respondía 202 sin nada que consultar.",
        "properties": {
          "id": {
            "type": "string",
            "example": "foqu_3b7f1e9d5c2a8"
          },
          "dte_type": {
            "type": "integer",
            "example": 33
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "result": {
            "type": "object",
            "description": "Lo que dijo el SII cuando la consulta terminó.",
            "properties": {
              "available": {
                "type": "integer",
                "nullable": true,
                "description": "Folios timbrados y sin emitir. `null` significa que no lo sabemos, no cero.",
                "example": 3
              },
              "max_per_request": {
                "type": "integer",
                "nullable": true,
                "description": "Máximo por solicitud vigente.",
                "example": 8
              },
              "last_timbraje": {
                "type": "string",
                "nullable": true
              },
              "timbrajes": {
                "type": "array",
                "description": "Rangos timbrados históricamente.",
                "items": {
                  "type": "object"
                }
              }
            }
          },
          "error": {
            "type": "string",
            "description": "Motivo cuando la consulta no terminó bien."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sii_environment": {
            "type": "string",
            "enum": [
              "production",
              "certification"
            ],
            "description": "Ambiente del SII en el que se hizo la operación. Un CAF de `certification` NO sirve para emitir."
          },
          "error_code": {
            "type": "string",
            "description": "Vocabulario cerrado del desenlace fallido; vacío si no hubo error. Ver la página de códigos de error.",
            "enum": [
              "",
              "certification_not_enabled",
              "missing_certificate",
              "no_folios_authorized",
              "sii_unavailable",
              "sii_unrecognized_page"
            ]
          }
        }
      },
      "WebhookCreate": {
        "type": "object",
        "required": [
          "master_entity_id",
          "url",
          "events"
        ],
        "properties": {
          "master_entity_id": {
            "type": "string",
            "description": "ID de la entidad maestra para la cual se crea el webhook",
            "example": "ment_4829301923847"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL del endpoint que recibirá las notificaciones"
          },
          "events": {
            "type": "array",
            "description": "Lista de eventos a notificar",
            "items": {
              "type": "string",
              "enum": [
                "document.issued",
                "document.delivered",
                "document.rejected",
                "document.trace_updated",
                "document.paid",
                "document.unpaid",
                "document.cancelled"
              ]
            },
            "minItems": 1
          },
          "secret": {
            "type": "string",
            "description": "Clave secreta para verificar la autenticidad de las notificaciones",
            "maxLength": 255
          },
          "is_active": {
            "type": "boolean",
            "description": "Si el webhook está activo",
            "default": true
          },
          "environment": {
            "type": "string",
            "enum": [
              "both",
              "production",
              "sandbox"
            ],
            "default": "both",
            "description": "De qué ambiente recibe eventos de documentos: `both` (default), `production` o `sandbox`. Los eventos que no son de documento (credenciales, folios, cobros, programados) se entregan como producción."
          },
          "api_version": {
            "type": "integer",
            "enum": [
              1,
              2
            ],
            "default": 2,
            "description": "Formato de los identificadores que viajan en el payload. `2`: todos los ids son public_id (`docu_…` documento, `ment_…` emisor/receptor, `scdo_…` programado, `fir_…` solicitud de folios, `dowe_…` webhook). `1`: ids enteros, el contrato de la API v1. Si se omite, el default sigue la ruta de creación: `/v2/webhooks/` crea en 2 y `/v1/webhooks/` crea en 1 (desde la plataforma, la versión que ya usa la empresa). Los webhooks creados antes de octubre 2026 quedaron en `1`: súbelos con PATCH o desde la plataforma."
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID único del webhook",
            "example": "dowe_2c9e5a1b7f3d0"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL del endpoint que recibe las notificaciones"
          },
          "events": {
            "type": "array",
            "description": "Lista de eventos configurados",
            "items": {
              "type": "string",
              "enum": [
                "document.issued",
                "document.delivered",
                "document.rejected",
                "document.trace_updated",
                "document.paid",
                "document.unpaid",
                "document.cancelled"
              ]
            }
          },
          "events_display": {
            "type": "array",
            "description": "Nombres legibles de los eventos",
            "items": {
              "type": "string"
            },
            "example": [
              "Emitido",
              "Entregado",
              "Rechazado SII"
            ]
          },
          "secret": {
            "type": "string",
            "description": "Clave secreta para verificar notificaciones",
            "nullable": true
          },
          "is_active": {
            "type": "boolean",
            "description": "Si el webhook está activo"
          },
          "last_status_code": {
            "type": "integer",
            "description": "Último código HTTP de respuesta",
            "nullable": true
          },
          "last_sent_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de último envío",
            "nullable": true
          },
          "success_rate": {
            "type": "number",
            "format": "float",
            "description": "Tasa de éxito de entregas (0-100)",
            "minimum": 0,
            "maximum": 100
          },
          "last_delivery": {
            "type": "object",
            "description": "Información de la última entrega",
            "nullable": true,
            "properties": {
              "id": {
                "type": "string",
                "description": "ID de la entrega",
                "example": "wede_5f1c2a9b7d3e0"
              },
              "event": {
                "type": "string",
                "description": "Evento de la entrega"
              },
              "is_success": {
                "type": "boolean",
                "description": "Si la entrega fue exitosa"
              },
              "status_code": {
                "type": "integer",
                "description": "Código HTTP de respuesta"
              },
              "sent_at": {
                "type": "string",
                "format": "date-time",
                "description": "Fecha y hora del envío"
              },
              "document_id": {
                "type": "integer",
                "description": "ID del documento"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización"
          },
          "environment": {
            "type": "string",
            "enum": [
              "both",
              "production",
              "sandbox"
            ],
            "description": "De qué ambiente recibe eventos de documentos: `both` (default), `production` o `sandbox`. Los eventos que no son de documento (credenciales, folios, cobros, programados) se entregan como producción."
          },
          "api_version": {
            "type": "integer",
            "enum": [
              1,
              2
            ],
            "description": "Formato de los identificadores que viajan en el payload. `2`: todos los ids son public_id (`docu_…` documento, `ment_…` emisor/receptor, `scdo_…` programado, `fir_…` solicitud de folios, `dowe_…` webhook). `1`: ids enteros, el contrato de la API v1. Si se omite, el default sigue la ruta de creación: `/v2/webhooks/` crea en 2 y `/v1/webhooks/` crea en 1 (desde la plataforma, la versión que ya usa la empresa). Los webhooks creados antes de octubre 2026 quedaron en `1`: súbelos con PATCH o desde la plataforma."
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "description": "Notificación enviada a la URL del webhook. Headers: `X-Pana-Event-Id`, `X-Pana-Event-Type`, `X-Pana-Timestamp`, `X-Pana-Delivery`, `X-Pana-Signature` (HMAC SHA-256 del cuerpo con el `secret`). Ver la guía de webhooks para el payload de cada evento.",
        "properties": {
          "event": {
            "type": "string",
            "description": "Tipo de evento",
            "enum": [
              "document.issued",
              "document.delivered",
              "document.rejected",
              "document.trace_updated",
              "document.paid",
              "document.unpaid",
              "document.cancelled",
              "scheduled_document.created",
              "scheduled_document.updated",
              "scheduled_document.executed",
              "scheduled_document.failed",
              "folio_request.completed",
              "folio_request.failed",
              "folio_request.authorized_without_caf",
              "credential.validated",
              "credential.invalid",
              "webhook.test"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora del evento (ISO 8601)"
          },
          "data": {
            "type": "object",
            "description": "Datos del evento. Para `document.*`:",
            "properties": {
              "id": {
                "type": "string",
                "example": "docu_8371029384756",
                "description": "public_id del documento (`api_version` 2). Con `api_version` 1 es el id entero."
              },
              "folio": {
                "type": "string",
                "nullable": true
              },
              "date_issued": {
                "type": "string",
                "format": "date"
              },
              "amount_with_iva": {
                "type": "number",
                "nullable": true
              },
              "is_sandbox": {
                "type": "boolean"
              },
              "dte_type": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "example": "33"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              },
              "sender": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "ment_4829301923847",
                    "description": "public_id de la empresa (`api_version` 2); entero con `api_version` 1"
                  },
                  "name": {
                    "type": "string"
                  },
                  "tax_id": {
                    "type": "string",
                    "example": "76.123.456-7"
                  },
                  "email": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "receiver": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "ment_7710084398120",
                    "description": "public_id de la empresa (`api_version` 2); entero con `api_version` 1"
                  },
                  "name": {
                    "type": "string"
                  },
                  "tax_id": {
                    "type": "string",
                    "example": "76.123.456-7"
                  },
                  "email": {
                    "type": "string",
                    "nullable": true
                  }
                },
                "nullable": true
              },
              "document_total": {
                "type": "object",
                "nullable": true
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "references": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "xml_file": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "URL del XML (presigned)"
              },
              "pdf_file": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "URL del PDF (presigned, solo en `document.issued`)"
              }
            }
          }
        }
      },
      "DocumentBatch": {
        "type": "object",
        "required": [
          "documents"
        ],
        "properties": {
          "documents": {
            "type": "array",
            "description": "Array de documentos a crear (máximo 200)",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          }
        }
      },
      "Document": {
        "type": "object",
        "required": [
          "dte_type",
          "document_issuer",
          "document_receiver",
          "details"
        ],
        "properties": {
          "date_issued": {
            "type": "string",
            "format": "date",
            "description": "Fecha de emisión (YYYY-MM-DD). Si X-Use-Defaults es true y no se proporciona, se usa la fecha actual."
          },
          "folio": {
            "type": "string",
            "description": "Folio del documento. Si X-Use-Defaults es true y no se proporciona, se genera automáticamente."
          },
          "dte_type": {
            "$ref": "#/components/schemas/DteType"
          },
          "document_issuer": {
            "$ref": "#/components/schemas/DocumentIssuer"
          },
          "document_receiver": {
            "$ref": "#/components/schemas/DocumentReceiver"
          },
          "details": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/DetailItem"
            }
          },
          "header": {
            "$ref": "#/components/schemas/DocumentHeader"
          },
          "references": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReferenceItem"
            }
          },
          "export_data": {
            "$ref": "#/components/schemas/ExportData"
          },
          "transport_data": {
            "$ref": "#/components/schemas/TransportData"
          },
          "json_param": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true,
            "description": "Campos propios del cliente (objeto JSON libre, ej. `{\"external_order_id\": \"PED-123\"}`). Se guarda tal cual con el documento, vuelve en `GET /documents/{document_id}/` y en el listado, y permite buscar el documento con `json_param__<key>=<valor>` en `GET /documents/`. Úsalo para guardar tu propio identificador (ej. el `Idempotency-Key` o el id de tu pedido) y así reencontrar el documento aunque pierdas la respuesta de creación.",
            "example": {
              "external_order_id": "PED-123"
            }
          },
          "additional_info": {
            "type": "string",
            "maxLength": 1000,
            "nullable": true,
            "description": "Texto libre (máximo 1000 caracteres) que se imprime en un recuadro \"Información adicional\" al final del PDF, justo antes del timbre. No se envía al SII: no forma parte del XML. Solo se imprime si tu empresa usa el PDF propio (PDF personalizado de Tu Pana) o emite con el facturador de mercado; en cualquier otro caso (PDF oficial del SII) el texto se guarda y se devuelve en la API, pero no aparece en el PDF. Los saltos de línea se respetan. No se puede modificar una vez emitido el documento.",
            "example": "Orden de compra N° 4500123 - Centro de costo: Operaciones"
          }
        }
      },
      "DteType": {
        "type": "object",
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Código del tipo de documento:\n- 33: Factura Electrónica\n- 34: Factura Exenta Electrónica\n- 39: Boleta Electrónica\n- 41: Boleta Exenta Electrónica\n- 46: Factura de Compra Electrónica\n- 52: Guía de Despacho Electrónica\n- 61: Nota de Crédito Electrónica\n- 80: Boleta de Honorarios Electrónica\n- 90: Boleta de Honorarios a Terceros Electrónica\n- 110: Factura de Exportación Electrónica",
            "enum": [
              "33",
              "34",
              "39",
              "41",
              "46",
              "52",
              "61",
              "80",
              "90",
              "110"
            ]
          }
        }
      },
      "DocumentHeader": {
        "type": "object",
        "properties": {
          "purchase_transaction_type": {
            "type": "string",
            "description": "Tipo de transacción de compra",
            "nullable": true
          },
          "sale_transaction_type": {
            "type": "string",
            "description": "Tipo de transacción de venta",
            "nullable": true
          },
          "payment_method": {
            "type": "string",
            "description": "Método de pago",
            "enum": [
              "1",
              "2",
              "3"
            ],
            "nullable": true
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de vencimiento",
            "nullable": true
          },
          "vat_withheld": {
            "type": "boolean",
            "description": "Indica si el IVA está retenido. Solo aplicable para facturas de compra (DTE 46) y notas de crédito que referencian facturas de compra.",
            "example": false,
            "nullable": true
          },
          "retention_type": {
            "type": "string",
            "description": "Tipo de retención obligatorio para boletas de honorarios (DTE 80, 90). Define quién retiene el 14,5% legal.",
            "enum": [
              "RETRECEPTOR",
              "RETCONTRIBUYENTE"
            ],
            "example": "RETRECEPTOR",
            "nullable": true
          },
          "purchase_type": {
            "type": "string",
            "description": "Tipo de compra para facturas recibidas en el SII",
            "enum": [
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7"
            ],
            "example": "1",
            "nullable": true
          }
        }
      },
      "DocumentIssuer": {
        "type": "object",
        "required": [
          "rut"
        ],
        "properties": {
          "rut": {
            "type": "string",
            "description": "RUT sin puntos y con guion, ej: 76543210-K. Si X-Use-Defaults es true, los demás campos se rellenarán automáticamente según la configuración.",
            "pattern": "^[0-9]{7,8}-[0-9K]$"
          },
          "business_name": {
            "type": "string",
            "description": "Razón social"
          },
          "phone_number": {
            "type": "string",
            "description": "Número de teléfono"
          },
          "email": {
            "type": "string",
            "description": "Correo electrónico"
          },
          "business_activity": {
            "type": "string",
            "description": "Giro comercial"
          },
          "activity_code": {
            "type": "integer",
            "description": "Código de actividad económica"
          },
          "sii_branch_code": {
            "type": "string",
            "description": "Código de sucursal SII"
          },
          "address": {
            "type": "string",
            "description": "Dirección"
          },
          "district": {
            "type": "string",
            "description": "Comuna"
          },
          "city": {
            "type": "string",
            "description": "Ciudad"
          }
        }
      },
      "DocumentReceiver": {
        "type": "object",
        "required": [
          "rut"
        ],
        "properties": {
          "rut": {
            "type": "string",
            "description": "RUT sin puntos y con guion, ej: 76543210-K. Si X-Use-Defaults es true, los demás campos se rellenarán automáticamente según la configuración.",
            "pattern": "^[0-9]{7,8}-[0-9K]$"
          },
          "business_name": {
            "type": "string",
            "description": "Razón social"
          },
          "contact": {
            "type": "string",
            "description": "Contacto"
          },
          "business_activity": {
            "type": "string",
            "description": "Giro comercial"
          },
          "address": {
            "type": "string",
            "description": "Dirección"
          },
          "district": {
            "type": "string",
            "description": "Comuna"
          },
          "city": {
            "type": "string",
            "description": "Ciudad"
          }
        }
      },
      "DetailItem": {
        "type": "object",
        "required": [
          "item_name",
          "quantity",
          "unit_price"
        ],
        "properties": {
          "item_name": {
            "type": "string",
            "description": "Nombre del ítem"
          },
          "quantity": {
            "type": "number",
            "description": "Cantidad"
          },
          "unit_price": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "description": "Precio unitario neto, sin IVA (no puede ser negativo)"
          },
          "gross_unit_price": {
            "type": "number",
            "format": "float",
            "description": "Precio unitario bruto, con IVA incluido. Solo válido para boletas electrónicas (dte_type 39 y 41); en cualquier otro tipo de documento la API responde 422. No se puede combinar con unit_price en el mismo documento: todas las líneas deben usar uno u otro. Si se envía, se usa como unit_price para calcular item_total, y el neto/IVA del documento se derivan a partir del bruto."
          },
          "is_exempt": {
            "type": "boolean",
            "default": false,
            "description": "Marca la línea como no afecta o exenta de IVA (Detalle/IndExe = 1): su monto va a exempt_amount y no genera IVA. Por ahora sólo en guía de despacho (DTE 52); en otro tipo de documento la API responde 422. No disponible para emisores del facturador gratuito del SII (422)."
          },
          "item_description": {
            "type": "string",
            "description": "Descripción del ítem"
          },
          "discount_percent": {
            "type": "number",
            "format": "float",
            "description": "Porcentaje de descuento"
          },
          "item_code": {
            "type": "string",
            "description": "Código del ítem"
          },
          "unit": {
            "type": "string",
            "description": "Unidad de medida"
          },
          "other_tax": {
            "type": "number",
            "format": "float",
            "description": "Otros impuestos"
          },
          "item_type_code": {
            "type": "integer",
            "description": "Código de tipo de ítem"
          },
          "line_number": {
            "type": "integer",
            "description": "Número de línea del ítem. Opcional: si no viene, se usa el orden del arreglo.",
            "example": 1
          },
          "item_total": {
            "type": "number",
            "description": "Total de la línea. La API lo recalcula a partir de quantity, unit_price y discount_percent; el valor enviado no se usa para emitir.",
            "example": 4050000
          },
          "show_item_type": {
            "type": "string",
            "enum": [
              "01",
              "02"
            ],
            "description": "Sólo boletas (39/41) de espectáculos emitidas por cuenta de terceros (ItemEspectaculo): \"01\" si la línea es la entrada, \"02\" si es el valor por servicio que cobra el emisor. Obligatorio en todas las líneas en ese caso.",
            "nullable": true
          },
          "ticket": {
            "type": "object",
            "nullable": true,
            "description": "Datos del ticket de la entrada (línea con show_item_type \"01\"). El SII exige imprimirlos en la boleta.",
            "properties": {
              "ticket_folio": {
                "type": "integer",
                "description": "Folio del ticket, único para el evento (máximo 6 dígitos)."
              },
              "generated_at": {
                "type": "string",
                "format": "date-time",
                "description": "Fecha y hora de generación del ticket."
              },
              "event_name": {
                "type": "string",
                "maxLength": 80,
                "description": "Nombre del espectáculo."
              },
              "ticket_type": {
                "type": "string",
                "maxLength": 10,
                "description": "Tipo de ticket."
              },
              "event_code": {
                "type": "string",
                "maxLength": 5,
                "description": "Código asociado al evento."
              },
              "event_datetime": {
                "type": "string",
                "format": "date-time",
                "description": "Fecha y hora de realización del evento."
              },
              "event_place": {
                "type": "string",
                "maxLength": 80,
                "description": "Dirección o recinto donde se realiza el evento."
              },
              "event_location": {
                "type": "string",
                "maxLength": 20,
                "description": "Sector o sección de la ubicación en el evento."
              },
              "row": {
                "type": "string",
                "maxLength": 3,
                "nullable": true,
                "description": "Fila de la ubicación."
              },
              "seat": {
                "type": "string",
                "maxLength": 3,
                "nullable": true,
                "description": "Asiento de la ubicación."
              }
            }
          }
        }
      },
      "ReferenceItem": {
        "type": "object",
        "required": [
          "reference_folio",
          "reference_date",
          "dte_type_code"
        ],
        "properties": {
          "reference_folio": {
            "type": "integer",
            "description": "Folio de referencia"
          },
          "reference_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de referencia"
          },
          "reference_reason": {
            "type": "string",
            "description": "Razón de referencia. Para notas de crédito totales debe ser 'ANULA DOCUMENTO DE LA REFERENCIA'.",
            "example": "ANULA DOCUMENTO DE LA REFERENCIA"
          },
          "dte_type_code": {
            "type": "string",
            "description": "Código del tipo de DTE del documento referenciado"
          }
        }
      },
      "BatchResponse": {
        "type": "object",
        "properties": {
          "batch_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del lote"
          },
          "status": {
            "type": "string",
            "description": "Estado del batch",
            "enum": [
              "created",
              "processing",
              "completed",
              "failed"
            ],
            "example": "processing"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora de creación del batch"
          },
          "documents": {
            "type": "array",
            "description": "Array de documentos procesados en el batch",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "description": "Índice del documento en el array original"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "processing",
                    "success",
                    "invalid",
                    "temporary_error",
                    "permanent_error",
                    "incomplete"
                  ],
                  "description": "Estado de procesamiento del documento"
                },
                "document": {
                  "type": "object",
                  "nullable": true,
                  "description": "Información completa del documento (solo presente si status permite tener documento)",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "description": "ID único del documento creado"
                    },
                    "folio": {
                      "type": "string",
                      "nullable": true,
                      "description": "Número de folio del documento"
                    },
                    "date_issued": {
                      "type": "string",
                      "format": "date",
                      "description": "Fecha de emisión del documento"
                    },
                    "amount_with_iva": {
                      "type": "number",
                      "format": "float",
                      "description": "Monto total con IVA"
                    },
                    "receiver_id": {
                      "type": "integer",
                      "nullable": true,
                      "description": "ID de la entidad receptora"
                    },
                    "is_draft": {
                      "type": "boolean",
                      "description": "Indica si el documento es un borrador"
                    },
                    "can_be_issued": {
                      "type": "boolean",
                      "description": "Indica si el documento puede ser emitido"
                    },
                    "dte_type": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Código del tipo de DTE"
                        },
                        "description": {
                          "type": "string"
                        }
                      }
                    },
                    "sender": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "tax_id": {
                          "type": "string"
                        }
                      }
                    },
                    "receiver": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "tax_id": {
                          "type": "string"
                        }
                      }
                    },
                    "items": {
                      "type": "array",
                      "description": "Array de productos/servicios del documento",
                      "items": {
                        "type": "object",
                        "properties": {
                          "item_name": {
                            "type": "string"
                          },
                          "item_description": {
                            "type": "string",
                            "nullable": true
                          },
                          "quantity": {
                            "type": "number",
                            "nullable": true
                          },
                          "unit_price": {
                            "type": "number",
                            "nullable": true
                          },
                          "unit": {
                            "type": "string",
                            "nullable": true
                          },
                          "item_code": {
                            "type": "string",
                            "nullable": true
                          },
                          "item_type_code": {
                            "type": "integer",
                            "nullable": true
                          },
                          "discount_percent": {
                            "type": "number",
                            "nullable": true
                          },
                          "other_tax": {
                            "type": "number",
                            "nullable": true
                          },
                          "is_exempt": {
                            "type": "boolean",
                            "description": "true si la línea es no afecta o exenta de IVA (IndExe = 1)."
                          }
                        }
                      }
                    },
                    "document_total": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "net_amount": {
                          "type": "number",
                          "nullable": true
                        },
                        "iva_rate": {
                          "type": "number",
                          "nullable": true
                        },
                        "iva_amount": {
                          "type": "number",
                          "nullable": true
                        },
                        "exempt_amount": {
                          "type": "number",
                          "nullable": true,
                          "description": "Monto exento: suma de las líneas con is_exempt en true. total_amount = net_amount + iva_amount + exempt_amount."
                        },
                        "total_amount": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    },
                    "pdf_url": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL presignada al PDF del documento (válida por 2 horas)"
                    },
                    "pdf_download_url": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL de descarga del PDF"
                    },
                    "retention_type": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tipo de retención para boletas de honorarios (DTE 80, 90)",
                      "enum": [
                        "RETRECEPTOR",
                        "RETCONTRIBUYENTE"
                      ]
                    },
                    "export_data": {
                      "type": "object",
                      "nullable": true,
                      "description": "Datos de exportación para facturas internacionales (DTE 110, 111, 112)"
                    }
                  }
                },
                "errors": {
                  "type": "object",
                  "nullable": true,
                  "description": "Errores de validación si el estado es 'invalid' o hay errores"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "description": "Avisos sobre campos desconocidos que se ignoraron (modo aviso). Sólo aparece si hay avisos. Con validación estricta, la API responde 422 en vez de avisar.",
            "items": {
              "$ref": "#/components/schemas/BatchWarning"
            }
          }
        }
      },
      "BatchWarning": {
        "type": "object",
        "description": "Aviso sobre un campo desconocido del documento: se ignoró al crear el documento. Las API keys con validación estricta reciben 422 en vez del aviso.",
        "properties": {
          "document_index": {
            "type": "integer",
            "description": "Posición del documento en el arreglo documents (desde 0).",
            "example": 0
          },
          "field": {
            "type": "string",
            "description": "Ruta del campo dentro del documento.",
            "example": "header.transfer_indicator"
          },
          "code": {
            "type": "string",
            "description": "unknown_field: campo desconocido (se ignoró). invalid_rut: RUT de transportista o chofer con dígito verificador inválido (se emitió igual).",
            "enum": [
              "unknown_field",
              "invalid_rut"
            ],
            "example": "unknown_field"
          },
          "message": {
            "type": "string",
            "description": "Texto para personas. Puede cambiar: no lo parsees.",
            "example": "Campo desconocido: se ignoró."
          },
          "suggestion": {
            "type": "string",
            "nullable": true,
            "description": "Campo correcto, si se reconoce el error (ej: header.transfer_indicator → transport_data.transport_type, export_data.export_clause → export_data.sale_clause_code, export_data.destination_country → export_data.destination_country_code). null si no hay sugerencia.",
            "example": "transport_data.transport_type"
          }
        }
      },
      "DocumentListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentDetail"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer",
                "nullable": true
              },
              "page_size": {
                "type": "integer",
                "nullable": true
              },
              "total": {
                "type": "integer"
              },
              "total_pages": {
                "type": "integer",
                "nullable": true
              }
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "next": {
                "type": "string",
                "nullable": true
              },
              "prev": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "DocumentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID único del documento",
            "example": "docu_9f2a7c1b8e4d0"
          },
          "folio": {
            "type": "string",
            "description": "Número de folio del documento",
            "nullable": true
          },
          "date_issued": {
            "type": "string",
            "format": "date",
            "description": "Fecha de emisión del documento"
          },
          "amount_with_iva": {
            "type": "number",
            "format": "float",
            "description": "Monto total con IVA"
          },
          "dte_type_code": {
            "type": "string",
            "description": "Código del tipo de DTE (ej: \"33\" para Factura Electrónica)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación del registro (ISO 8601)"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización (ISO 8601)"
          },
          "has_trace": {
            "type": "boolean",
            "description": "true si el documento tiene al menos una traza registrada del SII."
          },
          "json_param": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true,
            "description": "Campos propios del cliente enviados en `json_param` al crear el documento. `null` si no se envió.",
            "example": {
              "external_order_id": "PED-123"
            }
          },
          "additional_info": {
            "type": "string",
            "nullable": true,
            "description": "Texto enviado en `additional_info` al crear el documento. `null` si no se envió. Solo se imprime en el PDF si la empresa usa el PDF propio de Tu Pana o el facturador de mercado.",
            "example": "Orden de compra N° 4500123 - Centro de costo: Operaciones"
          }
        }
      },
      "LatestTraceInfo": {
        "type": "object",
        "description": "Resumen liviano de la última traza del documento. Siempre se incluye en las respuestas de listado y detalle (es `null` cuando el documento no tiene trazas).",
        "nullable": true,
        "properties": {
          "has_acknowledgments": {
            "type": "boolean",
            "description": "El documento tiene un acuse de recibo (eventos ACD o ERM)."
          },
          "has_claims": {
            "type": "boolean",
            "description": "El documento tiene al menos un reclamo (RCD, RFP o RFT)."
          },
          "is_more_than_eight_days": {
            "type": "boolean",
            "description": "Han pasado más de 8 días desde la recepción (relevante para mérito ejecutivo)."
          },
          "is_rejected": {
            "type": "boolean",
            "description": "Calculado: el documento fue rechazado (existe un evento RCD, RFP o RFT)."
          },
          "date_reception": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora en que el SII registró la recepción del documento.",
            "nullable": true
          },
          "events_count": {
            "type": "integer",
            "description": "Cantidad total de eventos en esta traza. Útil para decidir si vale la pena solicitar `?include_trace_events=true` en el listado."
          }
        }
      },
      "DocumentDetailWithFiles": {
        "type": "object",
        "allOf": [
          {
            "$ref": "#/components/schemas/DocumentDetail"
          },
          {
            "type": "object",
            "properties": {
              "amount_iva": {
                "type": "number",
                "format": "float",
                "description": "Monto del IVA",
                "nullable": true
              },
              "amount_without_iva": {
                "type": "number",
                "format": "float",
                "description": "Monto sin IVA",
                "nullable": true
              },
              "currency": {
                "type": "string",
                "description": "Moneda del documento",
                "enum": [
                  "CLP",
                  "UF",
                  "USD",
                  "EUR"
                ],
                "example": "CLP"
              },
              "sender_id": {
                "type": "integer",
                "description": "ID de la entidad emisora"
              },
              "sender_name": {
                "type": "string",
                "description": "Nombre de la entidad emisora"
              },
              "sender_tax_id": {
                "type": "string",
                "description": "RUT de la entidad emisora"
              },
              "receiver_id": {
                "type": "string",
                "description": "ID de la entidad receptora (como string, puede ser null para algunos tipos de documentos)",
                "nullable": true
              },
              "receiver_name": {
                "type": "string",
                "description": "Nombre de la entidad receptora",
                "nullable": true
              },
              "receiver_tax_id": {
                "type": "string",
                "description": "RUT de la entidad receptora",
                "nullable": true
              },
              "has_credit_note": {
                "type": "boolean",
                "description": "Indica si el documento tiene una nota de crédito asociada"
              },
              "is_paid": {
                "type": "boolean",
                "description": "Indica si el documento está marcado como pagado"
              },
              "traces": {
                "type": "array",
                "description": "Array de trazas del documento en el SII, cada una con su lista de `events`. En el endpoint de detalle siempre se incluye; en el endpoint de listado solo se incluye cuando se pasa `include_trace_events=true`.",
                "items": {
                  "$ref": "#/components/schemas/Trace"
                }
              },
              "vat_withheld": {
                "type": "boolean",
                "description": "Indica si se retuvo IVA",
                "nullable": true
              },
              "exchange_rate": {
                "type": "string",
                "description": "Tipo de cambio para facturas internacionales",
                "nullable": true
              },
              "original_amount": {
                "type": "string",
                "description": "Monto original en moneda extranjera para facturas internacionales",
                "nullable": true
              },
              "state": {
                "type": "string",
                "description": "Estado del documento (draft, issued, etc.)",
                "nullable": true
              },
              "dte_type_description": {
                "type": "string",
                "description": "Descripción del tipo de DTE"
              },
              "pdf": {
                "type": "string",
                "format": "uri",
                "description": "URL presignada al PDF del documento (válida por tiempo limitado, generalmente 1 hora)",
                "nullable": true
              },
              "xml": {
                "type": "string",
                "description": "Contenido completo del XML del documento tributario electrónico",
                "nullable": true
              },
              "xml_error": {
                "type": "string",
                "description": "Mensaje de error si no se pudo obtener el XML (null si está disponible)",
                "nullable": true
              },
              "references": {
                "type": "array",
                "description": "Array de documentos referenciados (para notas de crédito, etc.)",
                "items": {
                  "$ref": "#/components/schemas/ReferenceItem"
                }
              },
              "details": {
                "type": "array",
                "description": "Array de productos/líneas del documento",
                "items": {
                  "$ref": "#/components/schemas/DetailItem"
                },
                "nullable": true
              },
              "header": {
                "$ref": "#/components/schemas/DocumentHeader",
                "description": "Información del encabezado del documento (transacción, pago, etc.)",
                "nullable": true
              },
              "document_issuer": {
                "$ref": "#/components/schemas/DocumentIssuer",
                "description": "Información completa del emisor del documento",
                "nullable": true
              },
              "document_receiver": {
                "$ref": "#/components/schemas/DocumentReceiver",
                "description": "Información completa del receptor del documento",
                "nullable": true
              },
              "document_total": {
                "type": "object",
                "nullable": true,
                "description": "Totales del documento",
                "properties": {
                  "net_amount": {
                    "type": "number",
                    "nullable": true,
                    "description": "Monto neto afecto (sin IVA)"
                  },
                  "iva_rate": {
                    "type": "number",
                    "nullable": true,
                    "description": "Tasa de IVA aplicada"
                  },
                  "iva_amount": {
                    "type": "number",
                    "nullable": true,
                    "description": "Monto del IVA"
                  },
                  "exempt_amount": {
                    "type": "number",
                    "nullable": true,
                    "description": "Monto exento: suma de las líneas con is_exempt en true. total_amount = net_amount + iva_amount + exempt_amount."
                  },
                  "total_amount": {
                    "type": "number",
                    "nullable": true,
                    "description": "Monto total"
                  }
                }
              },
              "transport_data": {
                "$ref": "#/components/schemas/TransportData",
                "description": "Datos de transporte del documento (guía de despacho DTE 52 y otros documentos con transporte), con todos los campos de TransportData",
                "nullable": true
              }
            }
          }
        ]
      },
      "Trace": {
        "type": "object",
        "description": "Traza del documento en el SII. Contiene los flags de acceso/estado y la lista de `events` con el detalle de cada hito (recepción, acuse, reclamo, etc.).",
        "properties": {
          "date_reception": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora en que el SII registró la recepción del documento.",
            "nullable": true
          },
          "has_receiver_access": {
            "type": "boolean",
            "description": "El receptor tiene acceso al documento en el portal del SII."
          },
          "has_issuer_access": {
            "type": "boolean",
            "description": "El emisor tiene acceso al documento en el portal del SII."
          },
          "has_holder_access": {
            "type": "boolean",
            "description": "El tenedor vigente tiene acceso al documento."
          },
          "is_paid_cash": {
            "type": "boolean",
            "description": "Documento marcado como pagado al contado en el SII."
          },
          "has_claims": {
            "type": "boolean",
            "description": "El documento tiene al menos un reclamo registrado (RCD, RFP o RFT)."
          },
          "is_more_than_eight_days": {
            "type": "boolean",
            "description": "Han pasado más de 8 días desde la recepción (relevante para mérito ejecutivo)."
          },
          "has_acknowledgments": {
            "type": "boolean",
            "description": "El documento tiene un acuse de recibo (ACD o ERM)."
          },
          "has_guide_reference": {
            "type": "boolean",
            "description": "El documento referencia una guía de despacho.",
            "nullable": true
          },
          "is_rejected": {
            "type": "boolean",
            "description": "Calculado: el documento fue rechazado (existe un evento RCD, RFP o RFT)."
          },
          "days_until_executive_merit": {
            "type": "integer",
            "description": "Días que faltan para que el documento entre en mérito ejecutivo (negativo si ya pasó). `null` si no aplica (sin recepción, con acuse o rechazado).",
            "nullable": true
          },
          "executive_merit_alert_level": {
            "type": "string",
            "description": "Nivel de alerta para mérito ejecutivo.",
            "enum": [
              "none",
              "warning",
              "critical"
            ]
          },
          "events": {
            "type": "array",
            "description": "Eventos registrados en el SII para esta traza (ordenados por fecha descendente).",
            "items": {
              "$ref": "#/components/schemas/TraceEvent"
            }
          }
        }
      },
      "TraceEvent": {
        "type": "object",
        "description": "Evento de trazabilidad del SII para un documento (ej: aceptación, reclamo, acuse).",
        "properties": {
          "event_code": {
            "type": "string",
            "description": "Código del evento del SII. Algunos comunes: `ACD` (acepta contenido), `ERM` (acuse de recibo), `RCD` (reclamo de contenido), `RFP` (reclamo forma de pago), `RFT` (reclamo forma de transporte), `NCA` (nota de crédito asociada).",
            "example": "ACD"
          },
          "event_description": {
            "type": "string",
            "description": "Descripción del evento entregada por el SII.",
            "example": "Acepta Contenido del Documento"
          },
          "event_date": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora del evento en zona horaria de Chile."
          },
          "responsable_rut": {
            "type": "integer",
            "description": "RUT (sin DV) de quien registró el evento en el SII.",
            "nullable": true
          },
          "responsable_dv": {
            "type": "string",
            "description": "Dígito verificador del RUT del responsable.",
            "nullable": true
          }
        }
      },
      "Error": {
        "required": [
          "error",
          "message"
        ],
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Código de error",
            "example": "VALIDATION_ERROR",
            "enum": [
              "VALIDATION_ERROR",
              "AUTHENTICATION_ERROR",
              "AUTHORIZATION_ERROR",
              "NOT_FOUND",
              "SII_ERROR",
              "INTERNAL_ERROR"
            ]
          },
          "message": {
            "type": "string",
            "description": "Mensaje de error"
          }
        }
      },
      "MasterEntity": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID entero de la entidad maestra (contrato v1). Para integraciones nuevas prefiere `opaque_id`.",
            "example": "ment_4829301923847"
          },
          "tax_id": {
            "type": "string",
            "description": "RUT de la entidad maestra",
            "example": "76.798.398-0"
          },
          "name": {
            "type": "string",
            "description": "Razón social de la entidad",
            "example": "SUPLO SPA"
          },
          "email": {
            "type": "string",
            "description": "Correo electrónico de contacto",
            "nullable": true,
            "example": null
          },
          "addresses": {
            "type": "array",
            "description": "Lista de direcciones de la entidad",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "ID único de la dirección",
                  "example": 6
                },
                "address": {
                  "type": "string",
                  "description": "Dirección completa",
                  "example": "AV TAJAMAR 183 OF 401   OFIC"
                },
                "district": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer",
                      "description": "ID único de la comuna",
                      "example": 7
                    },
                    "name": {
                      "type": "string",
                      "description": "Nombre de la comuna",
                      "example": "LAS CONDES"
                    },
                    "city": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "ID único de la ciudad",
                          "example": 3
                        },
                        "name": {
                          "type": "string",
                          "description": "Nombre de la ciudad",
                          "example": "SANTIAGO"
                        }
                      }
                    }
                  }
                },
                "sii_branch_code": {
                  "type": "string",
                  "description": "Código de sucursal SII",
                  "nullable": true,
                  "example": null
                },
                "phone": {
                  "type": "string",
                  "description": "Teléfono de la sucursal",
                  "nullable": true,
                  "example": null
                }
              }
            }
          },
          "activities": {
            "type": "array",
            "description": "Lista de actividades económicas de la entidad",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "ID único de la actividad",
                  "example": 1
                },
                "code": {
                  "type": "string",
                  "description": "Código de actividad económica",
                  "example": "620900"
                },
                "name": {
                  "type": "string",
                  "description": "Nombre de la actividad económica",
                  "example": "OTRAS ACTIVIDADES DE TECNOLOGIA DE LA IN"
                }
              }
            }
          }
        }
      },
      "ScheduledDocumentReferenceItem": {
        "type": "object",
        "description": "Referencia a un documento (ej. para notas de crédito). Máximo 3 referencias por documento programado.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de la referencia (solo en respuesta)",
            "example": "scdo_6f1d8b3a9e2c7"
          },
          "dte_type_code": {
            "type": "string",
            "description": "Código del tipo de DTE del documento referenciado (ej: 33, 61)",
            "example": "33"
          },
          "reference_folio": {
            "type": "string",
            "description": "Folio del documento referenciado",
            "example": "123"
          },
          "reference_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha del documento referenciado (YYYY-MM-DD)",
            "example": "2024-01-15"
          },
          "reference_reason": {
            "type": "string",
            "description": "Razón de la referencia. Para notas de crédito totales: 'ANULA DOCUMENTO DE LA REFERENCIA'.",
            "nullable": true,
            "example": "ANULA DOCUMENTO DE LA REFERENCIA"
          }
        }
      },
      "ScheduledDocumentListResponse": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Total de documentos programados",
            "example": 25
          },
          "next": {
            "type": "string",
            "nullable": true,
            "description": "URL de la siguiente página",
            "example": "https://api.tupana.ai/v1/scheduled-documents?master_entity_id=123&page=2"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "description": "URL de la página anterior",
            "example": null
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocument"
            }
          }
        }
      },
      "ScheduledDocument": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID único del documento programado",
            "example": "scdo_6f1d8b3a9e2c7"
          },
          "sender": {
            "type": "object",
            "description": "Información de la entidad emisora",
            "properties": {
              "id": {
                "type": "integer",
                "example": 123
              },
              "name": {
                "type": "string",
                "example": "Empresa Ejemplo SpA"
              },
              "rut": {
                "type": "string",
                "example": "76543210-1"
              }
            }
          },
          "receiver": {
            "type": "object",
            "nullable": true,
            "description": "Información de la entidad receptora",
            "properties": {
              "id": {
                "type": "integer",
                "example": 456
              },
              "name": {
                "type": "string",
                "example": "Cliente ABC Ltda"
              },
              "rut": {
                "type": "string",
                "example": "12345678-9"
              }
            }
          },
          "dte_type": {
            "type": "object",
            "description": "Tipo de documento tributario",
            "properties": {
              "id": {
                "type": "integer",
                "example": 1
              },
              "code": {
                "type": "string",
                "example": "33"
              },
              "description": {
                "type": "string",
                "example": "Factura Electrónica"
              }
            }
          },
          "frequency": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly",
              "quarterly",
              "semiannual",
              "yearly"
            ],
            "description": "Frecuencia de ejecución",
            "example": "monthly"
          },
          "frequency_display": {
            "type": "string",
            "description": "Frecuencia en formato legible",
            "example": "Mensual"
          },
          "day_of_month": {
            "type": "integer",
            "nullable": true,
            "description": "Día del mes en que se ejecutará el documento (1-31). Requerido para frecuencias: monthly, quarterly, semiannual, yearly. Si el día no existe en un mes (ej: 31 en febrero), se usará el último día del mes.",
            "example": 15
          },
          "day_of_week": {
            "type": "integer",
            "nullable": true,
            "description": "Día de la semana para ejecución (1=Lunes, 7=Domingo)",
            "example": null
          },
          "next_execution": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha y hora de la próxima ejecución",
            "example": "2024-02-15T10:00:00Z"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "completed"
            ],
            "description": "Estado del documento programado",
            "example": "active"
          },
          "status_display": {
            "type": "string",
            "description": "Estado en formato legible",
            "example": "Activo"
          },
          "amount": {
            "type": "number",
            "description": "Monto del documento",
            "example": 100000
          },
          "currency": {
            "type": "string",
            "enum": [
              "CLP",
              "UF",
              "USD",
              "EUR"
            ],
            "description": "Moneda del documento",
            "example": "CLP"
          },
          "currency_day": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 31,
            "description": "Día del mes (1-31) para tomar el valor del tipo de cambio. Aplica cuando la moneda es UF o USD; si no se indica, se usa el día de emisión.",
            "example": 10
          },
          "completed_occurrences": {
            "type": "integer",
            "description": "Número de veces que se ha ejecutado",
            "example": 5
          },
          "max_occurrences": {
            "type": "integer",
            "nullable": true,
            "description": "Número máximo de ejecuciones",
            "example": null
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Fecha de inicio de la programación (YYYY-MM-DD). Define desde cuándo comenzará a ejecutarse el documento programado. Si no se proporciona, se usa la fecha actual. La primera ejecución será calculada a partir de esta fecha según la frecuencia configurada.",
            "example": "2024-02-01"
          },
          "emission_day_adjustment": {
            "type": "string",
            "enum": [
              "none",
              "next",
              "previous"
            ],
            "description": "Ajuste de fecha de emisión a días hábiles: 'none' (sin ajuste), 'next' (próximo día hábil), 'previous' (anterior día hábil)",
            "default": "none",
            "example": "none"
          },
          "end_type": {
            "type": "string",
            "enum": [
              "never",
              "on_date",
              "after_occurrences"
            ],
            "description": "Tipo de finalización de la programación: 'never' (nunca finaliza, se ejecuta indefinidamente), 'on_date' (finaliza en una fecha específica, requiere end_date), 'after_occurrences' (finaliza después de un número máximo de ejecuciones, requiere max_occurrences). Por defecto: 'never'.",
            "default": "never",
            "example": "never"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Fecha de finalización de la programación (YYYY-MM-DD). Solo aplica y es requerido si end_type es 'on_date'. El documento programado dejará de ejecutarse después de esta fecha.",
            "example": "2024-12-31"
          },
          "details": {
            "type": "array",
            "description": "Detalles/productos del documento",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentDetail"
            }
          },
          "references": {
            "type": "array",
            "maxItems": 3,
            "description": "Referencias a documentos (ej. factura anulada por nota de crédito). Máximo 3 referencias.",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentReferenceItem"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de creación",
            "example": "2024-01-15T10:00:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha de última actualización",
            "example": "2024-01-20T15:30:00Z"
          }
        }
      },
      "ScheduledDocumentCreate": {
        "type": "object",
        "required": [
          "sender",
          "dte_type",
          "frequency",
          "details",
          "receiver_tax_id"
        ],
        "properties": {
          "sender": {
            "type": "integer",
            "description": "ID de la entidad maestra emisora (obligatorio)",
            "example": 123
          },
          "dte_type": {
            "type": "string",
            "description": "Código del tipo de DTE (ej: '33' para Factura Electrónica)",
            "example": "33"
          },
          "receiver_tax_id": {
            "type": "string",
            "description": "RUT del receptor (formato: 12345678-9). El sistema buscará un cliente existente con este RUT. Si no existe, creará uno nuevo automáticamente. Campo requerido.",
            "example": "12345678-9"
          },
          "frequency": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly",
              "quarterly",
              "semiannual",
              "yearly"
            ],
            "description": "Frecuencia de ejecución del documento programado. Valores: 'daily' (diario), 'weekly' (semanal), 'monthly' (mensual), 'quarterly' (trimestral), 'semiannual' (semestral), 'yearly' (anual).",
            "example": "monthly"
          },
          "day_of_month": {
            "type": "integer",
            "description": "Día del mes en que se ejecutará el documento (1-31). Requerido para frecuencias: monthly, quarterly, semiannual, yearly. Si el día no existe en un mes (ej: 31 en febrero), se usará el último día del mes.",
            "minimum": 1,
            "maximum": 31,
            "example": 15
          },
          "day_of_week": {
            "type": "integer",
            "description": "Día de la semana en que se ejecutará el documento (1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo). Requerido para frecuencia semanal (weekly).",
            "minimum": 1,
            "maximum": 7,
            "example": 1
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de inicio de la programación (YYYY-MM-DD). Define desde cuándo comenzará a ejecutarse el documento programado. Si no se proporciona, se usa la fecha actual. La primera ejecución será calculada a partir de esta fecha según la frecuencia configurada.",
            "example": "2024-02-01"
          },
          "emission_day_adjustment": {
            "type": "string",
            "enum": [
              "none",
              "next",
              "previous"
            ],
            "description": "Ajuste de fecha de emisión a días hábiles. Si la fecha calculada cae en fin de semana o feriado, se ajusta según esta opción: 'none' (sin ajuste, emite en la fecha calculada aunque sea fin de semana), 'next' (ajusta al próximo día hábil), 'previous' (ajusta al anterior día hábil). Por defecto: 'none'.",
            "default": "none",
            "example": "none"
          },
          "end_type": {
            "type": "string",
            "enum": [
              "never",
              "on_date",
              "after_occurrences"
            ],
            "description": "Tipo de finalización de la programación: 'never' (nunca finaliza, se ejecuta indefinidamente), 'on_date' (finaliza en una fecha específica, requiere end_date), 'after_occurrences' (finaliza después de un número máximo de ejecuciones, requiere max_occurrences). Por defecto: 'never'.",
            "default": "never",
            "example": "never"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de finalización de la programación (YYYY-MM-DD). Solo aplica y es requerido si end_type es 'on_date'. El documento programado dejará de ejecutarse después de esta fecha.",
            "example": "2024-12-31"
          },
          "currency": {
            "type": "string",
            "description": "Moneda del documento",
            "enum": [
              "CLP",
              "UF",
              "USD",
              "EUR"
            ],
            "default": "CLP",
            "example": "CLP"
          },
          "currency_day": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 31,
            "description": "Día del mes (1-31) para tomar el valor del tipo de cambio (UF o USD). Si no se indica, se usa el día de emisión.",
            "example": 10
          },
          "references": {
            "type": "array",
            "maxItems": 3,
            "description": "Referencias a documentos (ej. factura anulada por nota de crédito). Máximo 3 referencias.",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentReferenceItem"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Estado inicial del documento programado",
            "default": "active",
            "example": "active"
          },
          "max_occurrences": {
            "type": "integer",
            "description": "Número máximo de ejecuciones (opcional, null = infinito). Solo aplica si end_type es 'after_occurrences'.",
            "minimum": 1,
            "example": 12
          },
          "details": {
            "type": "array",
            "description": "Detalles/productos del documento",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentDetailCreate"
            }
          }
        }
      },
      "ScheduledDocumentUpdate": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive"
            ],
            "description": "Estado del documento programado",
            "example": "inactive"
          },
          "amount": {
            "type": "number",
            "description": "Monto total del documento",
            "minimum": 0,
            "example": 120000
          },
          "frequency": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly",
              "quarterly",
              "semiannual",
              "yearly"
            ],
            "description": "Frecuencia de ejecución del documento programado. Valores: 'daily' (diario), 'weekly' (semanal), 'monthly' (mensual), 'quarterly' (trimestral), 'semiannual' (semestral), 'yearly' (anual).",
            "example": "weekly"
          },
          "day_of_month": {
            "type": "integer",
            "description": "Día del mes en que se ejecutará el documento (1-31). Requerido para frecuencias: monthly, quarterly, semiannual, yearly. Si el día no existe en un mes (ej: 31 en febrero), se usará el último día del mes.",
            "minimum": 1,
            "maximum": 31,
            "example": 20
          },
          "day_of_week": {
            "type": "integer",
            "description": "Día de la semana en que se ejecutará el documento (1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo). Requerido para frecuencia semanal (weekly).",
            "minimum": 1,
            "maximum": 7,
            "example": 2
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de inicio de la programación (YYYY-MM-DD). Define desde cuándo comenzará a ejecutarse el documento programado. La primera ejecución será calculada a partir de esta fecha según la frecuencia configurada.",
            "example": "2024-02-01"
          },
          "emission_day_adjustment": {
            "type": "string",
            "enum": [
              "none",
              "next",
              "previous"
            ],
            "description": "Ajuste de fecha de emisión a días hábiles. Si la fecha calculada cae en fin de semana o feriado, se ajusta según esta opción: 'none' (sin ajuste, emite en la fecha calculada aunque sea fin de semana), 'next' (ajusta al próximo día hábil), 'previous' (ajusta al anterior día hábil).",
            "example": "none"
          },
          "end_type": {
            "type": "string",
            "enum": [
              "never",
              "on_date",
              "after_occurrences"
            ],
            "description": "Tipo de finalización de la programación: 'never' (nunca finaliza, se ejecuta indefinidamente), 'on_date' (finaliza en una fecha específica, requiere end_date), 'after_occurrences' (finaliza después de un número máximo de ejecuciones, requiere max_occurrences).",
            "example": "never"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de finalización de la programación (YYYY-MM-DD). Solo aplica y es requerido si end_type es 'on_date'. El documento programado dejará de ejecutarse después de esta fecha.",
            "example": "2024-12-31"
          },
          "max_occurrences": {
            "type": "integer",
            "nullable": true,
            "description": "Número máximo de ejecuciones. Solo aplica y es requerido si end_type es 'after_occurrences'. El documento programado dejará de ejecutarse después de alcanzar este número de ejecuciones.",
            "minimum": 1,
            "example": 24
          },
          "currency_day": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 31,
            "description": "Día del mes (1-31) para tomar el valor del tipo de cambio (UF o USD). Si no se indica, se usa el día de emisión.",
            "example": 10
          },
          "references": {
            "type": "array",
            "maxItems": 3,
            "description": "Referencias a documentos (ej. factura anulada por nota de crédito). Máximo 3 referencias. Si se envía, reemplaza todas las referencias existentes.",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentReferenceItem"
            }
          },
          "details": {
            "type": "array",
            "description": "Detalles/productos del documento. Si se envía, reemplaza todos los detalles existentes. Misma estructura que en creación.",
            "items": {
              "$ref": "#/components/schemas/ScheduledDocumentDetailCreate"
            }
          }
        }
      },
      "ScheduledDocumentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID único del detalle",
            "example": "scdo_6f1d8b3a9e2c7"
          },
          "item_name": {
            "type": "string",
            "description": "Nombre del producto o servicio",
            "example": "Servicio mensual de consultoría"
          },
          "item_description": {
            "type": "string",
            "description": "Descripción del producto o servicio",
            "example": "Consultoría especializada en tecnología"
          },
          "quantity": {
            "type": "number",
            "description": "Cantidad",
            "example": 1
          },
          "unit_price": {
            "type": "number",
            "minimum": 0,
            "description": "Precio unitario sin IVA (no puede ser negativo)",
            "example": 100000
          },
          "unit_of_measurement": {
            "type": "string",
            "description": "Unidad de medida",
            "example": "UN"
          },
          "item_code": {
            "type": "string",
            "description": "Código del producto o servicio según el sistema del emisor. Este código aparece en el documento emitido y puede ser usado para identificación interna del producto.",
            "nullable": true,
            "example": "PROD-001"
          },
          "item_type_code": {
            "type": "string",
            "description": "Código de tipo de ítem según clasificación SII. Identifica la categoría del producto o servicio (ej: '1' para productos, '2' para servicios).",
            "nullable": true,
            "example": "1"
          }
        }
      },
      "TransportData": {
        "type": "object",
        "description": "Datos de transporte de la guía de despacho (DTE 52): tipo de traslado, tipo de despacho, transportista, chofer, destino y datos de Aduana. Los campos de transporte y destino también se aceptan en otros tipos de documento; los de Aduana, sólo con transport_type 8 o 9. Con timber_enabled en true se incluyen los datos de origen de la madera que exige el SII (CONAF). Res. Ex. SII N°154 (vigente desde el 2026-11-01): tipo de traslado, patente, RUT del transportista, chofer (o transport_unknown_reason), destino con comuna, fecha y hora de salida y unidad de medida en cada línea pasan a ser obligatorios en la guía; hasta esa fecha la respuesta del batch sólo trae un aviso (warnings, code res154_*). Con emisores del facturador gratuito del SII (MiPyme), los datos de Aduana y el destino de la madera no están disponibles: la API responde 422; tipo de despacho, destino, salida, llegada, patente del carro y motivos se imprimen como texto en la primera línea del detalle porque el formulario del SII no tiene esos campos.",
        "properties": {
          "transport_type": {
            "type": "string",
            "description": "Tipo de traslado (IdDoc/IndTraslado). 1=Operación constituye venta, 2=Ventas por efectuar, 3=Consignaciones, 4=Entrega gratuita, 5=Traslados internos, 6=Otros traslados no venta, 7=Devolución de mercaderías, 8=Traslado para exportación (no venta), 9=Venta para exportación. Si no se envía, se usa 1.",
            "enum": [
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9"
            ],
            "default": "1",
            "example": "1"
          },
          "dispatch_type": {
            "type": "string",
            "nullable": true,
            "description": "Tipo de despacho (IdDoc/TipoDespacho). 1=Por cuenta del receptor (el cliente retira), 2=Por cuenta del emisor a instalaciones del cliente, 3=Por cuenta del emisor a otras instalaciones. Si no se envía, se emite 3. No se permite con transport_type 5 (422). Con emisores del facturador gratuito del SII (MiPyme) va como texto en la primera línea del detalle (su formulario no tiene el campo).",
            "enum": [
              "1",
              "2",
              "3"
            ],
            "example": "2"
          },
          "transport_rut": {
            "type": "string",
            "nullable": true,
            "description": "RUT de la empresa de transporte (Transporte/RUTTrans), formato 12345678-9. Si el dígito verificador es inválido se emite igual y la respuesta trae un aviso invalid_rut.",
            "example": "76234567-6"
          },
          "transport_plate": {
            "type": "string",
            "nullable": true,
            "description": "Patente del vehículo (Transporte/Patente). Se normaliza a mayúsculas sin guion ni espacios y queda en máximo 8 caracteres.",
            "example": "PJRL69"
          },
          "driver_rut": {
            "type": "string",
            "nullable": true,
            "description": "RUT del chofer (Transporte/Chofer/RUTChofer). Si el dígito verificador es inválido se emite igual y la respuesta trae un aviso invalid_rut. Se envía junto con driver_name, o ninguno de los dos (422 si falta uno).",
            "example": "12345678-5"
          },
          "driver_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre completo del chofer (Transporte/Chofer/NombreChofer). Se trunca a 30 caracteres en el DTE. Se envía junto con driver_rut, o ninguno de los dos (422 si falta uno).",
            "example": "Juan Pérez"
          },
          "destination_address": {
            "type": "string",
            "nullable": true,
            "maxLength": 70,
            "description": "Dirección de destino (Transporte/DirDest). Se informa cuando el destino es distinto de la dirección del receptor. Con emisores del facturador gratuito del SII (MiPyme) va como texto en la primera línea del detalle (su formulario no tiene el campo).",
            "example": "Aeropuerto Arturo Merino Benitez"
          },
          "destination_district": {
            "type": "string",
            "nullable": true,
            "maxLength": 20,
            "description": "Comuna de destino (Transporte/CmnaDest). Con emisores del facturador gratuito del SII (MiPyme) va como texto en la primera línea del detalle (su formulario no tiene el campo).",
            "example": "Pudahuel"
          },
          "destination_city": {
            "type": "string",
            "nullable": true,
            "maxLength": 20,
            "description": "Ciudad de destino (Transporte/CiudadDest). Con emisores del facturador gratuito del SII (MiPyme) va como texto en la primera línea del detalle (su formulario no tiene el campo).",
            "example": "Santiago"
          },
          "transfer_issuer_code": {
            "type": "string",
            "nullable": true,
            "enum": [
              "1",
              "2",
              "3",
              "4"
            ],
            "description": "Quién realiza el traslado de exportación (Emisor/GuiaExport/CdgTraslado): 1=Exportador, 2=Agente de Aduana, 3=Vendedor, 4=Contribuyente autorizado expresamente por el SII. Sólo con transport_type 8 o 9 (422 en otro caso); obligatorio con 8 o 9 en el facturador de mercado (sin él el SII acepta la guía con reparo HED-2-804). No disponible para emisores del facturador gratuito del SII (422).",
            "example": "1"
          },
          "authorization_resolution_number": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Número de la resolución del SII que autoriza al contribuyente a emitir la guía de exportación (Emisor/GuiaExport/FolioAut). Obligatorio con transfer_issuer_code 4 y no permitido con otro código (422).",
            "example": 1234
          },
          "authorization_resolution_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Fecha de la resolución del SII que autoriza al contribuyente (Emisor/GuiaExport/FchAut), formato YYYY-MM-DD. Obligatoria con transfer_issuer_code 4 y no permitida con otro código (422).",
            "example": "2024-03-01"
          },
          "departure_port_code": {
            "type": "string",
            "nullable": true,
            "description": "Puerto de embarque (Aduana/CodPtoEmbarque). Código o nombre exacto de la tabla de puertos de Aduana del SII (ej: 992 o AEROP.A.M.BENITEZ; 906=SAN ANTONIO, 905=VALPARAISO). Sólo con transport_type 8 o 9 (422 en otro caso); obligatorio con 8 o 9 en el facturador de mercado. No disponible para emisores del facturador gratuito del SII (422).",
            "example": "992"
          },
          "arrival_port_code": {
            "type": "string",
            "nullable": true,
            "description": "Puerto de desembarque (Aduana/CodPtoDesemb). Código o nombre exacto de la tabla de puertos de Aduana del SII (ej: 134=NEW YORK, 292=SANTOS). Sólo con transport_type 8 o 9 (422 en otro caso); obligatorio con 8 o 9 en el facturador de mercado. No disponible para emisores del facturador gratuito del SII (422).",
            "example": "134"
          },
          "gross_weight": {
            "type": "string",
            "format": "decimal",
            "nullable": true,
            "pattern": "^\\d{1,10}(\\.\\d{1,2})?$",
            "description": "Peso bruto de la carga (Aduana/PesoBruto), mayor a 0 y con hasta 2 decimales. Sólo con transport_type 8 o 9 (422 en otro caso); obligatorio con 8 o 9 en el facturador de mercado. No disponible para emisores del facturador gratuito del SII (422).",
            "example": "1414.00"
          },
          "gross_weight_unit_code": {
            "type": "string",
            "nullable": true,
            "description": "Unidad del peso bruto (Aduana/CodUnidPesoBruto), según la tabla de unidades de medida de Aduana del SII (ej: 6=KN). Sólo con transport_type 8 o 9 (422 en otro caso); obligatorio con 8 o 9 en el facturador de mercado. No disponible para emisores del facturador gratuito del SII (422).",
            "example": "6"
          },
          "total_packages": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Total de bultos (Aduana/TotBultos), mayor a 0. Si se envía, package_type_code es obligatorio. Sólo con transport_type 8 o 9 (422 en otro caso). No disponible para emisores del facturador gratuito del SII (422).",
            "example": 3
          },
          "package_type_code": {
            "type": "string",
            "nullable": true,
            "description": "Tipo de bulto (Aduana/TipoBultos/CodTpoBultos), según la tabla de tipos de bulto de Aduana del SII (ej: 22=CAJA DE CARTON). Obligatorio si se envía total_packages. Sólo con transport_type 8 o 9 (422 en otro caso). No disponible para emisores del facturador gratuito del SII (422).",
            "example": "22"
          },
          "timber_enabled": {
            "type": "boolean",
            "description": "Si es true, la guía incluye los datos de origen de la madera para CONAF.",
            "default": false,
            "example": false
          },
          "comuna_rol": {
            "type": "string",
            "nullable": true,
            "description": "Código de comuna del SII del rol del predio de origen.",
            "example": "13101"
          },
          "manzana_rol": {
            "type": "string",
            "nullable": true,
            "description": "Manzana del rol del predio de origen.",
            "example": "12"
          },
          "predio_rol": {
            "type": "string",
            "nullable": true,
            "description": "Predio del rol del predio de origen.",
            "example": "345"
          },
          "geo_ref_system": {
            "type": "string",
            "nullable": true,
            "description": "Código del sistema de referencia geográfica (ej: 1 = WGS84).",
            "example": "1"
          },
          "latitude": {
            "type": "string",
            "nullable": true,
            "description": "Latitud del origen de la madera, como string (normalmente con dos decimales, según el SII).",
            "example": "-33.45"
          },
          "longitude": {
            "type": "string",
            "nullable": true,
            "description": "Longitud del origen de la madera, como string (normalmente con dos decimales, según el SII).",
            "example": "-70.65"
          },
          "conaf_plan_code": {
            "type": "string",
            "nullable": true,
            "description": "Código del plan de manejo forestal de CONAF.",
            "example": "PM-2024-001"
          },
          "trailer_plate": {
            "type": "string",
            "nullable": true,
            "description": "Patente del carro o remolque (Transporte/PatenteCarro), cuando el vehículo lleva uno. Se normaliza igual que transport_plate: mayúsculas, sin guion ni espacios, máximo 8 caracteres. Res. Ex. SII N°154.",
            "example": "JK1234"
          },
          "departure_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Fecha de inicio del traslado (Transporte/FchSalida), AAAA-MM-DD. Res. Ex. SII N°154: obligatoria en la guía desde el 2026-11-01.",
            "example": "2026-11-02"
          },
          "departure_time": {
            "type": "string",
            "nullable": true,
            "description": "Hora de inicio del traslado (Transporte/HraSalida), HH:MM (también se acepta HH:MM:SS). Res. Ex. SII N°154: obligatoria en la guía desde el 2026-11-01.",
            "example": "08:30"
          },
          "arrival_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Fecha estimada de llegada (Transporte/FchLlegada), AAAA-MM-DD. No puede ser anterior a departure_date (422).",
            "example": "2026-11-02"
          },
          "transfer_reason": {
            "type": "string",
            "maxLength": 200,
            "description": "Motivo del traslado. Res. Ex. SII N°154: en un traslado que no es venta (transport_type distinto de 1 y 9) permite omitir el precio unitario de las líneas. Se imprime en el detalle del documento.",
            "example": "Traslado a bodega central para reposición de stock"
          },
          "transport_unknown_reason": {
            "type": "string",
            "maxLength": 100,
            "description": "Declaración expresa de que no se conocen los datos del transporte (patente, RUT del transportista, chofer) y por qué. Res. Ex. SII N°154 y nota 4 del Formato DTE 2026-02: desde el 2026-11-01 la guía se rechaza sin patente, transportista y chofer salvo que venga esta declaración. Se imprime en el detalle del documento.",
            "example": "El cliente retira con transporte propio no informado"
          },
          "destination_commune_role": {
            "type": "string",
            "pattern": "^\\d{1,6}$",
            "description": "Rol predial de destino de la madera: comuna (ManejoMadera/ComunaRolDestino). Sólo con timber_enabled en true y emisor del facturador de mercado; Res. Ex. SII N°75 de 2024, obligatorio desde el 2026-11-01.",
            "example": "13101"
          },
          "destination_block_role": {
            "type": "string",
            "pattern": "^\\d{1,6}$",
            "description": "Rol predial de destino de la madera: manzana (ManejoMadera/MnzRolDestino). Sólo con timber_enabled en true y emisor del facturador de mercado.",
            "example": "1234"
          },
          "destination_property_role": {
            "type": "string",
            "pattern": "^\\d{1,6}$",
            "description": "Rol predial de destino de la madera: predio (ManejoMadera/PrdRolDestino). Sólo con timber_enabled en true y emisor del facturador de mercado.",
            "example": "56"
          },
          "work_execution_notice": {
            "type": "string",
            "maxLength": 40,
            "description": "Número del aviso de ejecución de faena de CONAF (ManejoMadera/AvisoEjecucionFaena). Sólo con timber_enabled en true y emisor del facturador de mercado.",
            "example": "AEF-2026-0457"
          },
          "destination_latitude": {
            "type": "string",
            "maxLength": 30,
            "description": "Latitud del destino de la madera (ManejoMadera/LatitudDestinoMadera). Sólo con timber_enabled en true y emisor del facturador de mercado.",
            "example": "-36.82"
          },
          "destination_longitude": {
            "type": "string",
            "maxLength": 30,
            "description": "Longitud del destino de la madera (ManejoMadera/LongitudDestinoMadera). Sólo con timber_enabled en true y emisor del facturador de mercado.",
            "example": "-73.05"
          }
        }
      },
      "ExportData": {
        "type": "object",
        "description": "Datos específicos para facturas de exportación (DTE 110) y notas de crédito de exportación (DTE 112). Solo requerido cuando se selecciona uno de estos tipos de documento.",
        "properties": {
          "tax_id_receptor": {
            "type": "string",
            "description": "Identificación tributaria del receptor en el país de destino"
          },
          "destination_country_code": {
            "type": "string",
            "description": "Código de país del SII del destino final de la mercadería (Aduana/CodPaisDestin). No es código ISO 3166-1. Si no se envían receiver_country_code ni receiver_nationality_code, también es el país y la nacionalidad del receptor. Ver /user-guide/export-countries",
            "example": "225"
          },
          "receiver_country_code": {
            "type": "string",
            "description": "Código de país del SII donde está el receptor (Aduana/CodPaisRecep), cuando es distinto del destino, por ejemplo en una triangulación. Opcional: si no se envía, se usa destination_country_code. Misma tabla que destination_country_code.",
            "example": "515"
          },
          "receiver_nationality_code": {
            "type": "string",
            "description": "Código de país del SII de la nacionalidad del receptor (Receptor/Extranjero/Nacionalidad). Opcional: si no se envía, se usa receiver_country_code y, si tampoco viene, destination_country_code. Misma tabla que destination_country_code.",
            "example": "515"
          },
          "currency_code": {
            "type": "string",
            "description": "Código de moneda del SII (tabla de Aduana). No es código ISO 4217. Ver /user-guide/export-currencies",
            "example": "13"
          },
          "exchange_rate": {
            "type": "string",
            "description": "Tipo de cambio aplicado",
            "example": "800.50"
          },
          "departure_port_code": {
            "type": "string",
            "description": "Código del puerto de embarque"
          },
          "arrival_port_code": {
            "type": "string",
            "description": "Código del puerto de desembarque"
          },
          "departure_port_name": {
            "type": "string",
            "description": "Nombre del puerto de embarque"
          },
          "arrival_port_name": {
            "type": "string",
            "description": "Nombre del puerto de desembarque"
          },
          "total_packages": {
            "type": "string",
            "description": "Número total de bultos"
          },
          "sale_mode_code": {
            "type": "string",
            "description": "Código de modalidad de venta"
          },
          "sale_clause_code": {
            "type": "string",
            "description": "Cláusula de venta / Incoterm (CodClauVenta del DTE). No confundir con sale_mode_code, que es la modalidad de venta. Se acepta el código del SII o el nombre del Incoterm: 1=CIF, 2=CFR, 3=EXW, 4=FAS, 5=FOB, 6=S/CL, 8=OTROS, 9=DDP, 10=FCA, 11=CPT, 12=CIP, 17=DAT, 18=DAP.",
            "example": "5"
          },
          "export_payment_method_code": {
            "type": "string",
            "description": "Forma de pago de exportación (FmaPagExp del DTE). No es header.payment_method, que no aplica a exportación. Se acepta el código del SII o el nombre: 1=COB1, 2=COBRANZA, 11=ACRED, 12=CBOF, 21=S/PAGO, 32=ANTICIPO, 50=ANT/COB, 60=ANT/CRED, 80=S/PAGO/COB. Si no se envía, se emite 21 (sin pago).",
            "example": "11"
          },
          "export_type": {
            "type": "string",
            "description": "Tipo de exportación",
            "default": "0"
          }
        }
      },
      "ScheduledDocumentDetailCreate": {
        "type": "object",
        "required": [
          "item_name",
          "quantity",
          "unit_price"
        ],
        "properties": {
          "item_name": {
            "type": "string",
            "description": "Nombre del producto o servicio",
            "example": "Servicio mensual de consultoría"
          },
          "item_description": {
            "type": "string",
            "description": "Descripción del producto o servicio (opcional)",
            "example": "Consultoría especializada en tecnología"
          },
          "quantity": {
            "type": "number",
            "description": "Cantidad",
            "minimum": 0.01,
            "example": 1
          },
          "unit_price": {
            "type": "number",
            "minimum": 0,
            "description": "Precio unitario sin IVA (no puede ser negativo)",
            "example": 100000
          },
          "unit": {
            "type": "string",
            "description": "Unidad de medida (opcional). Para UF/USD se asigna automáticamente.",
            "example": "UN"
          },
          "item_code": {
            "type": "string",
            "description": "Código del ítem",
            "nullable": true,
            "example": "PROD-001"
          },
          "item_type_code": {
            "type": "string",
            "description": "Código de tipo de ítem",
            "nullable": true,
            "example": "1"
          }
        }
      },
      "SyncStatusType": {
        "type": "object",
        "description": "Última actualización de un tipo de scrape para la entidad",
        "properties": {
          "scrape_type": {
            "type": "string",
            "enum": [
              "ISSUED_DOCS",
              "RECEIVED_DOCS",
              "RECEIVED_HONORARY_BILLS",
              "THIRD_PARTY_HONORARY",
              "EMITTED_HONORARY_BILLS",
              "PURCHASE_BOOK",
              "SALE_BOOK",
              "BOOK_SUMMARY"
            ],
            "description": "Tipo de scrape: ISSUED_DOCS (facturas emitidas), RECEIVED_DOCS (facturas recibidas), RECEIVED_HONORARY_BILLS (boletas de honorarios recibidas), THIRD_PARTY_HONORARY (boletas de honorarios de terceros), EMITTED_HONORARY_BILLS (boletas de honorarios emitidas), PURCHASE_BOOK (libro de compras), SALE_BOOK (libro de ventas), BOOK_SUMMARY (resumen de libro de compras/ventas).",
            "example": "ISSUED_DOCS"
          },
          "last_success_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Fecha/hora de la última sincronización exitosa de este tipo. null si nunca ha cargado con éxito.",
            "example": "2026-07-20T06:12:41Z"
          },
          "last_status": {
            "type": "string",
            "enum": [
              "in_progress",
              "completed",
              "failed"
            ],
            "description": "Estado de la última ejecución de este tipo de scrape",
            "example": "completed"
          }
        }
      },
      "SyncRequest": {
        "type": "object",
        "description": "Solicitud de sincronización a demanda (recurso asíncrono)",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de la solicitud public ID (`ment_...`).",
            "example": "ment_4829301923847"
          },
          "master_entity_id": {
            "type": "string",
            "description": "ID entero de la entidad sincronizada public ID (`ment_...`).",
            "example": "ment_4829301923847"
          },
          "requested_types": {
            "type": "array",
            "description": "Tipos de scrape pedidos. Lista vacía = todos los tipos habilitados para la entidad.",
            "items": {
              "type": "string",
              "enum": [
                "ISSUED_DOCS",
                "RECEIVED_DOCS",
                "RECEIVED_HONORARY_BILLS",
                "THIRD_PARTY_HONORARY",
                "EMITTED_HONORARY_BILLS",
                "PURCHASE_BOOK",
                "SALE_BOOK",
                "BOOK_SUMMARY"
              ]
            },
            "example": [
              "ISSUED_DOCS",
              "RECEIVED_DOCS"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "description": "Estado de la solicitud: pending (creada, en cola), processing (scrapes corriendo), completed (todos los tipos terminaron OK), failed (al menos un tipo falló).",
            "example": "pending"
          },
          "webhook_url": {
            "type": "string",
            "description": "URL registrada para notificar al completar. String vacío si no se registró webhook.",
            "example": "https://miapp.cl/webhooks/tupana-sync"
          },
          "results": {
            "type": "object",
            "description": "Resultado por tipo de scrape al terminar. Las claves son los scrape_type ejecutados y cada valor es un objeto con `success` (boolean) más contadores como `new_documents`, o `error` si falló. Objeto vacío mientras la solicitud está pending/processing.",
            "additionalProperties": {
              "type": "object"
            },
            "example": {
              "ISSUED_DOCS": {
                "success": true,
                "new_documents": 3
              },
              "RECEIVED_DOCS": {
                "success": true,
                "new_documents": 0
              }
            }
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Fecha/hora en que terminó de procesarse. null mientras está pending/processing.",
            "example": "2026-07-20T14:34:12Z"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Fecha/hora de creación de la solicitud",
            "example": "2026-07-20T14:30:00Z"
          }
        }
      },
      "WebhookUpdate": {
        "type": "object",
        "description": "Campos editables de un webhook. Todos opcionales (PATCH).",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL del endpoint que recibirá las notificaciones"
          },
          "events": {
            "type": "array",
            "description": "Lista de eventos a notificar",
            "items": {
              "type": "string",
              "enum": [
                "document.issued",
                "document.delivered",
                "document.rejected",
                "document.trace_updated",
                "document.paid",
                "document.unpaid",
                "document.cancelled"
              ]
            },
            "minItems": 1
          },
          "secret": {
            "type": "string",
            "description": "Clave secreta para verificar la autenticidad de las notificaciones",
            "maxLength": 255
          },
          "is_active": {
            "type": "boolean",
            "description": "Si el webhook está activo",
            "default": true
          },
          "environment": {
            "type": "string",
            "enum": [
              "both",
              "production",
              "sandbox"
            ],
            "default": "both",
            "description": "De qué ambiente recibe eventos de documentos: `both` (default), `production` o `sandbox`. Los eventos que no son de documento (credenciales, folios, cobros, programados) se entregan como producción."
          },
          "api_version": {
            "type": "integer",
            "enum": [
              1,
              2
            ],
            "default": 2,
            "description": "Formato de los identificadores que viajan en el payload. `2`: todos los ids son public_id (`docu_…` documento, `ment_…` emisor/receptor, `scdo_…` programado, `fir_…` solicitud de folios, `dowe_…` webhook). `1`: ids enteros, el contrato de la API v1. Si se omite, el default sigue la ruta de creación: `/v2/webhooks/` crea en 2 y `/v1/webhooks/` crea en 1 (desde la plataforma, la versión que ya usa la empresa). Los webhooks creados antes de octubre 2026 quedaron en `1`: súbelos con PATCH o desde la plataforma."
          }
        }
      },
      "BookDocumentItem": {
        "type": "object",
        "description": "Un documento tal como aparece en el libro de compras o ventas del SII para la entidad y el período consultados. Los montos son enteros en pesos, tal como los informa el SII.",
        "properties": {
          "document_id": {
            "type": "string",
            "description": "Public ID del documento (`docu_...`). Úsalo en `GET /documents/{id}/` para el PDF, XML y líneas.",
            "example": "docu_7291038456120"
          },
          "operation": {
            "type": "string",
            "enum": [
              "COMPRA",
              "VENTA"
            ],
            "description": "Libro al que pertenece la fila."
          },
          "period": {
            "type": "string",
            "description": "Período tributario YYYYMM en que el SII clasifica el documento en este libro.",
            "example": "202603"
          },
          "dte_type_code": {
            "type": "integer",
            "description": "Código de tipo de documento SII (33, 34, 61, etc.).",
            "example": 33
          },
          "folio": {
            "type": "string",
            "example": "12345"
          },
          "issue_date": {
            "type": "string",
            "format": "date",
            "description": "Fecha de emisión del documento según el SII.",
            "example": "2026-03-10"
          },
          "counterparty": {
            "$ref": "#/components/schemas/BookDocumentCounterparty"
          },
          "reception_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Fecha de recepción en el SII. Solo en COMPRA."
          },
          "acknowledgment_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Fecha del acuse de recibo."
          },
          "claimed_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Fecha del reclamo, si lo hubo."
          },
          "receiver_event": {
            "type": "object",
            "nullable": true,
            "description": "Evento registrado por el receptor (acuse, reclamo, etc.).",
            "properties": {
              "code": {
                "type": "string",
                "nullable": true,
                "example": "A"
              },
              "label": {
                "type": "string",
                "nullable": true,
                "example": "Acuse de recibo"
              }
            }
          },
          "transaction_type": {
            "type": "object",
            "nullable": true,
            "description": "Tipo de transacción declarado en el libro de compras (del giro, activo fijo, etc.). Solo en COMPRA.",
            "properties": {
              "code": {
                "type": "integer",
                "nullable": true,
                "example": 1
              },
              "description": {
                "type": "string",
                "nullable": true,
                "example": "Del Giro"
              }
            }
          },
          "cancelled": {
            "type": "boolean",
            "nullable": true,
            "description": "Documento anulado según el SII."
          },
          "exempt_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto exento."
          },
          "net_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto neto."
          },
          "vat_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto IVA."
          },
          "total_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto total."
          },
          "taxes": {
            "$ref": "#/components/schemas/BookDocumentTaxes"
          },
          "reference": {
            "type": "object",
            "nullable": true,
            "description": "Documento referenciado (notas de crédito y débito).",
            "properties": {
              "dte_type_code": {
                "type": "integer",
                "nullable": true,
                "example": 33
              },
              "folio": {
                "type": "string",
                "nullable": true,
                "example": "12345"
              }
            }
          },
          "sii_branch_code": {
            "type": "integer",
            "nullable": true,
            "description": "Código de sucursal SII."
          },
          "synced_at": {
            "type": "string",
            "format": "date-time",
            "description": "Última vez que esta fila se actualizó desde el SII."
          }
        }
      },
      "BookDocumentCounterparty": {
        "type": "object",
        "description": "Contraparte del documento: el emisor en COMPRA, el receptor en VENTA.",
        "properties": {
          "rut": {
            "type": "string",
            "nullable": true,
            "example": "77222333-4"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "PROVEEDOR SPA"
          }
        }
      },
      "BookDocumentTaxes": {
        "type": "object",
        "description": "Desglose de impuestos del Registro de Compras y Ventas. Montos enteros en pesos; `null` cuando el SII no informa el campo.",
        "properties": {
          "fixed_asset_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto neto activo fijo."
          },
          "fixed_asset_vat_amount": {
            "type": "integer",
            "nullable": true,
            "description": "IVA activo fijo."
          },
          "non_recoverable_vat_amount": {
            "type": "integer",
            "nullable": true,
            "description": "IVA no recuperable."
          },
          "non_recoverable_code": {
            "type": "integer",
            "nullable": true,
            "description": "Código del IVA no recuperable."
          },
          "no_credit_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Monto sin derecho a crédito."
          },
          "common_use_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA uso común."
          },
          "total_withheld_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA retenido total."
          },
          "partial_withheld_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA retenido parcial."
          },
          "non_withheld_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA no retenido."
          },
          "own_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA propio."
          },
          "third_party_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA de terceros."
          },
          "out_of_term_vat": {
            "type": "integer",
            "nullable": true,
            "description": "IVA fuera de plazo."
          },
          "other_taxes_amount": {
            "type": "integer",
            "nullable": true,
            "description": "Otros impuestos (DTOI), por ejemplo impuestos adicionales."
          },
          "tax_rate": {
            "type": "string",
            "nullable": true,
            "description": "Tasa de IVA aplicada.",
            "example": "19"
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "API Key para autenticación. Debe proporcionarse en el header Authorization con el formato: 'Api-Key YOUR-API-KEY' (incluye el prefijo 'Api-Key ' seguido de tu API key)"
      }
    }
  }
}
