{"openapi":"3.0.0","info":{"title":"Notta API","version":"1.0.0","description":"Facturación electrónica chilena (SII) API-first: DTE 33/34/52/56/61, 110/112, CAF y certificados. Mismo contrato para el dashboard, la API REST y el servidor MCP remoto.","termsOfService":"https://notta.cl/legal/terms","contact":{"name":"Notta","url":"https://notta.cl/docs"}},"servers":[{"url":"https://app.notta.cl/api/v1"}],"externalDocs":{"description":"Documentación de Notta","url":"https://notta.cl/docs"},"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key Bearer token (`Authorization: Bearer ntt_prod_…`). Creala en https://app.notta.cl/app/api-keys#crear."},"oauth2":{"type":"oauth2","description":"OAuth 2.1 con PKCE (S256) y registro dinámico de cliente, para el servidor MCP remoto. El consumidor pide el mínimo que necesita: cada operación declara su scope en `security`.","flows":{"authorizationCode":{"authorizationUrl":"https://app.notta.cl/oauth/authorize","tokenUrl":"https://app.notta.cl/oauth/token","refreshUrl":"https://app.notta.cl/oauth/token","scopes":{"dte:read":"Leer tus documentos tributarios (emitidos y recibidos), su estado ante el SII y sus eventos.","rcv:read":"Leer el Registro de Compras y Ventas (RCV) que Notta sincroniza desde el SII.","empresas:read":"Leer los datos de tu empresa, tus contrapartes y el avance de tu certificación ante el SII.","certificates:read":"Leer el inventario de certificados digitales de tu empresa: metadata, nunca el archivo .p12 ni su clave.","billing:read":"Leer tu plan, el consumo del mes y tus pagos.","recepcion:read":"Leer la bandeja de compras que llegan por tu Casilla de Intercambio, con el plazo legal ya computado.","dte:write":"Emitir documentos tributarios a tu nombre (factura, nota de crédito, nota de débito, guía de despacho) y pedirle al SII el estado de un documento cuyo seguimiento se detuvo.","recepcion:write":"Proponer el acuse o el reclamo de una factura de un proveedor ante el SII. Por MCP cada acción espera SIEMPRE tu aprobación: es irreversible."}}}}},"schemas":{"ErrorResponse":{"type":"object","properties":{"code":{"type":"string","example":"validation_failed"},"message":{"type":"string"},"hint":{"type":"string"},"next_action":{"type":"string","example":"fix_body_and_retry"},"request_id":{"type":"string"},"detail":{"type":"object","additionalProperties":{"nullable":true}},"docs_url":{"type":"string","description":"Link a la fila de este `code` en el catálogo de errores. Presente para todo código documentado; ausente (nunca roto) para los que no lo están.","example":"https://notta.cl/docs/errors#e-caf.not_found"},"issues":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Zod issues[]: solo presente en code=validation_failed"}},"required":["code","message"],"description":"Error envelope común de la API ({ code, message, hint?, next_action?, request_id? })"},"EstadoDte":{"type":"object","properties":{"code":{"type":"string","description":"El mismo valor que `sii_status`, repetido aquí para que el bloque se explique solo. NO es un enum cerrado a propósito: el SII no publica una lista cerrada de códigos. Su instructivo termina la tabla con «Otros (no enumerados)», y Notta guarda verbatim lo que responde, así que puede traer uno que el catálogo no conozca (en producción ya aparecieron `106` y `107`). Un código desconocido llega clasificado como NO terminal, `en_proceso` y `contactar_soporte`, nunca como éxito.","example":"-11"},"label":{"type":"string","description":"Glosa corta en español, para mostrar. AGREGA información al código, no lo reemplaza."},"descripcion":{"type":"string","description":"Qué pasó y qué significa, en prosa. Está para que no haya que inferir la causa: un `-11` es el código con que FALLA la consulta de estado mientras el SII todavía no registra el envío recién subido, no un estado del documento, y es el camino normal."},"terminal":{"type":"boolean","description":"`true` ⇒ el SII ya dio su veredicto y volver a preguntar no puede devolver otra cosa. Es la CONDICIÓN DE CORTE de cualquier bucle de espera: cortar por `sii_status === \"EPR\"` deja el bucle vivo para siempre ante un rechazo. `stuck` y `sin_permiso_sii` son `false` a propósito (no hay veredicto), pero tampoco avanzan solos: mira `accion`."},"poll_activo":{"type":"boolean","description":"`true` ⇒ Notta tiene un poll durable consultando al SII por este documento ahora mismo; no hay nada que hacer más que volver a leer. `false` junto con `terminal: false` significa que nadie está mirando este documento: ahí `accion` dice qué lo destraba."},"categoria":{"type":"string","enum":["en_proceso","aceptado","rechazado","requiere_accion","archivistico"],"description":"Cómo terminó, o por qué no terminó: `en_proceso`: el SII todavía no dio veredicto; `aceptado`: veredicto favorable: el documento vale; `rechazado`: veredicto desfavorable: el SII no aceptó el documento; `requiere_accion`: no hay veredicto y no lo va a haber sin que alguien haga algo; `archivistico`: el SII ya lo aceptó en su momento; no hay envío que consultar."},"accion":{"type":"string","enum":["esperar","reintentar_consulta","reemitir","contactar_soporte","accion_en_sii","ninguna"],"description":"Qué hacer, en un enum ESTABLE pensado para que un agente ramifique sin leer la prosa, el equivalente de `next_action` en el contrato de errores: `esperar`: el poll converge solo; vuelve a leer más tarde; `reintentar_consulta`: `POST /dtes/{id}/refresh-status` destraba el caso; `reemitir`: el folio quedó quemado; emite uno nuevo corregido (nunca una Nota de Crédito: un documento rechazado no fue aceptado y no hay nada que anular); `contactar_soporte`: el dueño del problema es Notta; el emisor no puede corregirlo solo; `accion_en_sii`: el emisor tiene que hacer algo en el portal del SII; `ninguna`: terminal favorable: no hay nada que hacer."}},"required":["code","label","descripcion","terminal","poll_activo","categoria","accion"],"description":"La clasificación de `sii_status`, publicada. `sii_status` NO cambia y NO se reemplaza: el código crudo sigue siendo el contrato y este bloque lo AGREGA. Sirve para decidir sin adivinar: `terminal` corta los bucles de espera, `accion` dice qué hacer, y un código que el catálogo no conoce igual cae en una casilla accionable."},"DteEmitInput":{"type":"object","properties":{"tipo_dte":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]},{"type":"number","enum":[110]},{"type":"number","enum":[112]}]},"correo_receptor":{"type":"array","nullable":true,"items":{"type":"string","maxLength":200,"format":"email"},"minItems":1,"maxItems":5},"rut_emisor":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"receptor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"razon_social":{"type":"string","minLength":1,"maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20}},"required":["rut","razon_social"]},"fecha_emision":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fecha de emisión AAAA-MM-DD. OPCIONAL: si se omite, el servidor usa HOY en zona Chile (America/Santiago). Ventana permitida: desde el día 1 del MES EN CURSO hasta hoy+7 días. Dentro del mes en curso la fecha es libre (la factura se fecha el día de la operación); el mes anterior está cerrado, incluso durante los primeros días del mes. Fuera de la ventana → 400 validation_failed, sin consumir folio. Una fecha PASADA es válida: el SII recibe el documento pero lo acepta CON REPAROS, y queda en el F29 del período de esa fecha."},"items":{"type":"array","items":{"type":"object","properties":{"nombre":{"type":"string","minLength":1,"maxLength":80},"descripcion":{"type":"string","minLength":1,"maxLength":1000},"cantidad":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":999999.999999},"unidad":{"type":"string","minLength":1,"maxLength":4},"precio_unitario":{"type":"number","minimum":0,"maximum":999999999999},"exento":{"type":"boolean"},"monto_item":{"type":"integer"},"descuento_pct":{"type":"number","minimum":0,"maximum":100,"description":"Descuento de la línea en porcentaje (0–100). El SII lo emite como <DescuentoPct>; monto_item debe venir ya descontado (= cantidad*precio_unitario − round(cantidad*precio_unitario*descuento_pct/100))."},"codigos":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"string","minLength":1,"maxLength":10},"valor":{"type":"string","minLength":1,"maxLength":35}},"required":["tipo","valor"]},"maxItems":5}},"required":["nombre","cantidad","precio_unitario","exento","monto_item"]},"minItems":1,"maxItems":60},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer","minimum":0},"iva":{"type":"integer"},"monto_total":{"type":"integer"},"descuento_global":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"string","enum":["descuento","recargo"]},"es_porcentaje":{"type":"boolean"},"valor":{"type":"number","minimum":0,"exclusiveMinimum":true},"glosa":{"type":"string","maxLength":45},"aplica_exento":{"type":"boolean"}},"required":["tipo","es_porcentaje","valor"]},"description":"Descuentos/recargos GLOBALES del documento (<DscRcgGlobal>, hasta 20). Cada uno: tipo (descuento|recargo), es_porcentaje (true=%/false=$ CLP), valor, glosa (opcional), aplica_exento (opcional, aplica sobre la base exenta). Reducen/aumentan el neto afecto antes del IVA. No aplica a Factura de Compra 46."},"certificate_id":{"type":"string","format":"uuid"},"emisor":{"type":"object","properties":{"giro":{"type":"string","minLength":1,"maxLength":80},"direccion":{"type":"string","minLength":1,"maxLength":70},"comuna":{"type":"string","minLength":1,"maxLength":20},"actividadEconomica":{"type":"integer","minimum":0,"exclusiveMinimum":true}}},"sii_env":{"type":"string","enum":["cert","prod"],"description":"Ambiente en que se emite. NO lo elige este campo: sale de la API key (`api_keys.sii_env`) y en el navegador del ambiente activo de la sesión. Mandarlo es OPCIONAL y funciona como confirmación: si contradice el ambiente de la credencial, la respuesta es 422 `dte.sii_env_credential_mismatch` y no se emite nada. Para emitir en el otro ambiente hay que usar una API key de ese ambiente."},"override_cedida":{"type":"boolean"},"override_plazo_anulacion":{"type":"boolean"},"forma_pago":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"pagos":{"type":"array","items":{"type":"object","properties":{"fecha":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"monto":{"type":"integer","minimum":0,"exclusiveMinimum":true},"glosa":{"type":"string","maxLength":40}},"required":["fecha","monto"]},"maxItems":30},"references":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"maxItems":40,"description":"Referencias comerciales (33/34: alias orden_compra/contrato/hes, o tipo_doc_ref con un código oficial de la tabla TpoDocRef del SII: 30–112 tributarios, 801–815/HES/HEM no tributarios) o correctivas (56/61: cod_ref ∈ {1,2,3})."}},"required":["tipo_dte","receptor","items"]},"Dte52EmitInput":{"type":"object","properties":{"tipo_dte":{"type":"number","enum":[52]},"rut_emisor":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"receptor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"razon_social":{"type":"string","minLength":1,"maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20}},"required":["rut","razon_social"]},"fecha_emision":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fecha de emisión YYYY-MM-DD. SOLO hacia adelante: desde HOY hasta HOY+7 días (zona Chile). Permite dejar lista una guía para un despacho de los próximos días. Una fecha pasada o a más de 7 días → 400 validation_failed."},"items":{"type":"array","items":{"type":"object","properties":{"nombre":{"type":"string","minLength":1,"maxLength":80},"descripcion":{"type":"string","minLength":1,"maxLength":1000},"cantidad":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":999999.999999},"unidad":{"type":"string","minLength":1,"maxLength":4},"precio_unitario":{"type":"number","minimum":0,"maximum":999999999999},"exento":{"type":"boolean"},"monto_item":{"type":"integer","minimum":0},"descuento_pct":{"type":"number","minimum":0,"maximum":100,"description":"Descuento de la línea en porcentaje (0–100). El SII lo emite como <DescuentoPct>; monto_item debe venir ya descontado (= cantidad*precio_unitario − round(cantidad*precio_unitario*descuento_pct/100))."},"codigos":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"string","minLength":1,"maxLength":10},"valor":{"type":"string","minLength":1,"maxLength":35}},"required":["tipo","valor"]},"maxItems":5}},"required":["nombre","cantidad","precio_unitario","exento","monto_item"]},"minItems":1,"maxItems":60},"monto_neto":{"type":"integer","minimum":0},"monto_exento":{"type":"integer","minimum":0},"iva":{"type":"integer","minimum":0},"monto_total":{"type":"integer","minimum":0},"certificate_id":{"type":"string","format":"uuid"},"sii_env":{"type":"string","enum":["cert","prod"],"description":"Ambiente en que se emite. NO lo elige este campo: sale de la API key (`api_keys.sii_env`) y en el navegador del ambiente activo de la sesión. Mandarlo es OPCIONAL y funciona como confirmación: si contradice el ambiente de la credencial, la respuesta es 422 `dte.sii_env_credential_mismatch` y no se emite nada. Para emitir en el otro ambiente hay que usar una API key de ese ambiente."},"references":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"maxItems":40,"description":"Referencias comerciales opcionales de la guía (orden_compra/contrato/hes o tipo_doc_ref)."},"despacho":{"type":"object","properties":{"ind_traslado":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]},{"type":"number","enum":[5]},{"type":"number","enum":[6]},{"type":"number","enum":[7]}]},"tipo_despacho":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"direccion_origen":{"type":"string","minLength":1,"maxLength":70},"comuna_origen":{"type":"string","minLength":1,"maxLength":20},"ciudad_origen":{"type":"string","minLength":1,"maxLength":20},"direccion_destino":{"type":"string","minLength":1,"maxLength":70},"comuna_destino":{"type":"string","minLength":1,"maxLength":20},"ciudad_destino":{"type":"string","minLength":1,"maxLength":20},"transportista":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"razon_social":{"type":"string","minLength":1,"maxLength":100}},"required":["rut","razon_social"]},"conductor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"nombre":{"type":"string","minLength":1,"maxLength":30}},"required":["rut","nombre"]},"vehiculo":{"type":"object","properties":{"patente":{"type":"string","minLength":1,"maxLength":8},"patente_carro":{"type":"string","minLength":1,"maxLength":8}},"required":["patente"]},"transporte_sin_informacion":{"type":"boolean"},"transporte_nota":{"type":"string","minLength":1,"maxLength":90}},"required":["ind_traslado","direccion_origen","comuna_origen","direccion_destino","comuna_destino"],"description":"Antecedentes de traslado y transporte (Res.154/2025). `ind_traslado` (1=venta, 2=venta por efectuar, 3=consignación, 5=traslado interno, 6=otros no venta, 7=devolución) es obligatorio. `tipo_despacho` (1/2/3) es obligatorio en todos los casos SALVO traslado interno (ind_traslado:5), donde NO se debe enviar: el receptor es el propio emisor, así que no hay 'por cuenta de quién', y mandarlo devuelve 400 validation_failed. Incluye origen/destino, transportista, conductor y vehículo."}},"required":["tipo_dte","rut_emisor","receptor","fecha_emision","items","despacho"]},"Dte56EmitInput":{"type":"object","properties":{"tipo_dte":{"type":"number","enum":[56]},"rut_emisor":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"receptor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"razon_social":{"type":"string","minLength":1,"maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20}},"required":["rut","razon_social"]},"correo_receptor":{"type":"array","nullable":true,"items":{"type":"string","maxLength":200,"format":"email"},"minItems":1,"maxItems":5},"fecha_emision":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"items":{"type":"array","items":{"type":"object","properties":{"nombre":{"type":"string","minLength":1,"maxLength":80},"descripcion":{"type":"string","minLength":1,"maxLength":1000},"cantidad":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":999999.999999},"unidad":{"type":"string","minLength":1,"maxLength":4},"precio_unitario":{"type":"number","minimum":0,"maximum":999999999999},"exento":{"type":"boolean"},"monto_item":{"type":"integer"},"descuento_pct":{"type":"number","minimum":0,"maximum":100,"description":"Descuento de la línea en porcentaje (0–100). El SII lo emite como <DescuentoPct>; monto_item debe venir ya descontado (= cantidad*precio_unitario − round(cantidad*precio_unitario*descuento_pct/100))."},"codigos":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"string","minLength":1,"maxLength":10},"valor":{"type":"string","minLength":1,"maxLength":35}},"required":["tipo","valor"]},"maxItems":5}},"required":["nombre","cantidad","precio_unitario","exento","monto_item"]},"minItems":1,"maxItems":60},"references":{"type":"array","items":{"type":"object","properties":{"line_num":{"type":"integer","minimum":1,"maximum":40},"tipo_doc_ref":{"type":"integer"},"folio_ref":{"anyOf":[{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},{"type":"string","pattern":"^[1-9]\\d*$"}]},"fecha_ref":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"cod_ref":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"razon_ref":{"type":"string","minLength":1,"maxLength":90}},"required":["line_num","tipo_doc_ref","folio_ref","fecha_ref","cod_ref","razon_ref"]},"minItems":1,"maxItems":40},"nd_reason":{"type":"string","enum":["correccion_monto","reposicion_nc_anulada","interese_moratorio_contractual"]},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer","minimum":0},"iva":{"type":"integer"},"monto_total":{"type":"integer"},"emisor":{"type":"object","properties":{"giro":{"type":"string","minLength":1,"maxLength":80},"direccion":{"type":"string","minLength":1,"maxLength":70},"comuna":{"type":"string","minLength":1,"maxLength":20},"actividadEconomica":{"type":"integer","minimum":0,"exclusiveMinimum":true}}},"certificate_id":{"type":"string","format":"uuid"},"sii_env":{"type":"string","enum":["cert","prod"],"description":"Ambiente en que se emite. NO lo elige este campo: sale de la API key (`api_keys.sii_env`) y en el navegador del ambiente activo de la sesión. Mandarlo es OPCIONAL y funciona como confirmación: si contradice el ambiente de la credencial, la respuesta es 422 `dte.sii_env_credential_mismatch` y no se emite nada. Para emitir en el otro ambiente hay que usar una API key de ese ambiente."}},"required":["tipo_dte","receptor","items","references","nd_reason"]},"Dte61EmitInput":{"type":"object","properties":{"tipo_dte":{"type":"number","enum":[61]},"rut_emisor":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"receptor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"razon_social":{"type":"string","minLength":1,"maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20}},"required":["rut","razon_social"]},"correo_receptor":{"type":"array","nullable":true,"items":{"type":"string","maxLength":200,"format":"email"},"minItems":1,"maxItems":5},"fecha_emision":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"items":{"type":"array","items":{"type":"object","properties":{"nombre":{"type":"string","minLength":1,"maxLength":80},"descripcion":{"type":"string","minLength":1,"maxLength":1000},"cantidad":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":999999.999999},"unidad":{"type":"string","minLength":1,"maxLength":4},"precio_unitario":{"type":"number","minimum":0,"maximum":999999999999},"exento":{"type":"boolean"},"monto_item":{"type":"integer"},"descuento_pct":{"type":"number","minimum":0,"maximum":100,"description":"Descuento de la línea en porcentaje (0–100). El SII lo emite como <DescuentoPct>; monto_item debe venir ya descontado (= cantidad*precio_unitario − round(cantidad*precio_unitario*descuento_pct/100))."},"codigos":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"string","minLength":1,"maxLength":10},"valor":{"type":"string","minLength":1,"maxLength":35}},"required":["tipo","valor"]},"maxItems":5}},"required":["nombre","cantidad","precio_unitario","exento","monto_item"]},"minItems":1,"maxItems":60},"references":{"type":"array","items":{"type":"object","properties":{"line_num":{"type":"integer","minimum":1,"maximum":40},"tipo_doc_ref":{"type":"integer"},"folio_ref":{"anyOf":[{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9007199254740991},{"type":"string","pattern":"^[1-9]\\d*$"}]},"fecha_ref":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"cod_ref":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"razon_ref":{"type":"string","minLength":1,"maxLength":90}},"required":["line_num","tipo_doc_ref","folio_ref","fecha_ref","cod_ref","razon_ref"]},"minItems":1,"maxItems":40},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer","minimum":0},"iva":{"type":"integer"},"monto_total":{"type":"integer"},"override_cedida":{"type":"boolean"},"override_plazo_anulacion":{"type":"boolean"},"nc_reason":{"type":"string","enum":["anulacion","devolucion","resciliacion","descuento_posterior","correccion_monto","correccion_texto"]},"emisor":{"type":"object","properties":{"giro":{"type":"string","minLength":1,"maxLength":80},"direccion":{"type":"string","minLength":1,"maxLength":70},"comuna":{"type":"string","minLength":1,"maxLength":20},"actividadEconomica":{"type":"integer","minimum":0,"exclusiveMinimum":true}}},"certificate_id":{"type":"string","format":"uuid"},"sii_env":{"type":"string","enum":["cert","prod"],"description":"Ambiente en que se emite. NO lo elige este campo: sale de la API key (`api_keys.sii_env`) y en el navegador del ambiente activo de la sesión. Mandarlo es OPCIONAL y funciona como confirmación: si contradice el ambiente de la credencial, la respuesta es 422 `dte.sii_env_credential_mismatch` y no se emite nada. Para emitir en el otro ambiente hay que usar una API key de ese ambiente."}},"required":["tipo_dte","receptor","items","references"]},"Dte110EmitInput":{"type":"object","properties":{"tipo_dte":{"anyOf":[{"type":"number","enum":[110]},{"type":"number","enum":[111]},{"type":"number","enum":[112]}]},"rut_emisor":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"fecha_emision":{"type":"string"},"receptor":{"type":"object","properties":{"rut":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$","default":"55555555-5"},"razon_social":{"type":"string","minLength":1,"maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20},"ciudad":{"type":"string","maxLength":20},"correo":{"type":"string","maxLength":80,"format":"email"},"extranjero":{"type":"object","properties":{"num_id":{"type":"string","maxLength":20},"nacionalidad":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"additionalProperties":false}},"required":["razon_social"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"nombre":{"type":"string","minLength":1,"maxLength":80},"descripcion":{"type":"string","minLength":1,"maxLength":1000},"cantidad":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":999999.999999},"unidad":{"type":"string","minLength":1,"maxLength":4},"precio_unitario":{"type":"number","minimum":0,"maximum":999999999999},"exento":{"type":"boolean","enum":[true]},"monto_item":{"type":"number","minimum":0}},"required":["nombre","cantidad","precio_unitario","monto_item"],"additionalProperties":false},"minItems":1,"maxItems":60},"tpo_moneda":{"type":"string","enum":["BOLIVAR","BOLIVIANO","CHELIN","CORONA DIN","CORONA NOR","CORONA SC","CRUZEIRO REAL","DIRHAM","DOLAR AUST","DOLAR CAN","DOLAR HK","DOLAR NZ","DOLAR SIN","DOLAR TAI","DOLAR USA","DRACMA","ESCUDO","EURO","FLORIN","FRANCO BEL","FRANCO FR","FRANCO SZ","GUARANI","LIBRA EST","LIRA","MARCO AL","MARCO FIN","NUEVO SOL","OTRAS MONEDAS","PESETA","PESO","PESO CL","PESO COL","PESO MEX","PESO URUG","RAND","RENMINBI","RUPIA","SUCRE","YEN"]},"ind_servicio":{"type":"integer"},"monto_exento":{"type":"number","minimum":0},"monto_total":{"type":"number","minimum":0},"aduana":{"type":"object","properties":{"cod_mod_venta":{"type":"integer","minimum":0,"exclusiveMinimum":true},"cod_clau_venta":{"type":"integer","minimum":0,"exclusiveMinimum":true},"tot_clau_venta":{"type":"number","minimum":0},"cod_via_transp":{"type":"integer","minimum":0,"exclusiveMinimum":true},"nombre_transp":{"type":"string","maxLength":40},"rut_cia_transp":{"type":"string","pattern":"^\\d{1,8}-[\\dKk]$"},"nombre_cia_transp":{"type":"string","maxLength":40},"id_adic_transp":{"type":"string","maxLength":20},"booking":{"type":"string","maxLength":20},"operador":{"type":"string","maxLength":20},"cod_pto_embarque":{"type":"integer","minimum":0,"exclusiveMinimum":true},"id_adic_pto_emb":{"type":"string","minLength":1,"maxLength":20},"cod_pto_desemb":{"type":"integer","minimum":0,"exclusiveMinimum":true},"id_adic_pto_desemb":{"type":"string","minLength":1,"maxLength":20},"tara":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":9999999},"cod_unid_med_tara":{"type":"integer","minimum":0,"exclusiveMinimum":true,"maximum":99},"peso_bruto":{"type":"number","minimum":0},"cod_unid_peso_bruto":{"type":"integer","minimum":0,"exclusiveMinimum":true},"peso_neto":{"type":"number","minimum":0},"cod_unid_peso_neto":{"type":"integer","minimum":0,"exclusiveMinimum":true},"tot_items":{"type":"integer","minimum":0},"tot_bultos":{"type":"integer","minimum":0},"tipo_bultos":{"type":"array","items":{"type":"object","properties":{"cod_tpo_bultos":{"type":"integer","minimum":0,"exclusiveMinimum":true},"cantidad_bultos":{"type":"integer","minimum":0},"marcas":{"type":"string","maxLength":40}},"required":["cod_tpo_bultos","cantidad_bultos"]},"maxItems":10},"mnt_flete":{"type":"number","minimum":0},"mnt_seguro":{"type":"number","minimum":0},"cod_pais_recep":{"type":"integer","minimum":0,"exclusiveMinimum":true},"cod_pais_destin":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"additionalProperties":false},"otra_moneda":{"type":"object","properties":{"tpo_moneda":{"type":"string","enum":["BOLIVAR","BOLIVIANO","CHELIN","CORONA DIN","CORONA NOR","CORONA SC","CRUZEIRO REAL","DIRHAM","DOLAR AUST","DOLAR CAN","DOLAR HK","DOLAR NZ","DOLAR SIN","DOLAR TAI","DOLAR USA","DRACMA","ESCUDO","EURO","FLORIN","FRANCO BEL","FRANCO FR","FRANCO SZ","GUARANI","LIBRA EST","LIRA","MARCO AL","MARCO FIN","NUEVO SOL","OTRAS MONEDAS","PESETA","PESO","PESO CL","PESO COL","PESO MEX","PESO URUG","RAND","RENMINBI","RUPIA","SUCRE","YEN"]},"tpo_cambio":{"type":"number","minimum":0,"exclusiveMinimum":true},"mnt_exe":{"type":"number","minimum":0},"mnt_total":{"type":"number","minimum":0}},"required":["tpo_moneda","tpo_cambio","mnt_total"],"additionalProperties":false},"referencias":{"type":"array","items":{"type":"object","properties":{"tipo_doc_ref":{"anyOf":[{"type":"string"},{"type":"number"}]},"folio_ref":{"anyOf":[{"type":"string"},{"type":"number"}]},"fecha_ref":{"type":"string"},"codigo_ref":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"type":"number","enum":[3]}]},"razon_ref":{"type":"string","maxLength":90}},"required":["tipo_doc_ref","folio_ref","fecha_ref"]}}},"required":["tipo_dte","receptor","items","tpo_moneda","monto_total"],"additionalProperties":false},"DteEmitAccepted":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Estado SII inicial (típicamente `queued`)\n\nVocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"folio":{"type":"integer"},"tipo_dte":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]},{"type":"number","enum":[110]},{"type":"number","enum":[112]}]},"rut_emisor":{"type":"string"},"rut_receptor":{"type":"string"},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer","description":"Monto exento del documento EN PESOS CHILENOS, siempre. 0 cuando no hay. En una exportación (110/112) NO es lo que declara la factura: el total exportado se registra aquí ya convertido, y el monto en su moneda viaja en `monto_moneda` con la moneda en `moneda_documento`. Vivía sólo en el DETALLE, así que cuadrar una exenta (34), o el exento de una 33 mixta, desde el listado costaba un `GET /dtes/{id}` por fila, que es el motivo por el que `monto_neto` e `iva` ya viajaban aquí."},"iva":{"type":"integer"},"monto_total":{"type":"integer"},"sii_env":{"type":"string","enum":["cert","prod"]},"sii_status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"estado":{"$ref":"#/components/schemas/EstadoDte"},"fecha_emision":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string"},"pdf":{"type":"string"},"xml":{"type":"string"},"events":{"type":"string"}},"required":["self","pdf","xml","events"]}},"required":["id","status","folio","tipo_dte","rut_emisor","rut_receptor","monto_neto","monto_exento","iva","monto_total","sii_env","sii_status","estado","fecha_emision","links"],"description":"DTE aceptado y encolado: el folio ya está asignado; el estado avanza async."},"PendingActionState":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","approved","rejected","expired"]},"kind":{"type":"string","enum":["emit_dte","recepcion_evento"]},"result_ref":{"type":"string","nullable":true,"format":"uuid","description":"El DTE que salió de la aprobación. Presente TAMBIÉN si el SII lo rechazó (D36)."},"rejection_reason":{"type":"string","nullable":true,"description":"El motivo que escribió la persona al rechazar (D41). null si no dijo por qué."},"expires_at":{"type":"string"},"resolved_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"next_action":{"type":"string","enum":["wait_for_human_approval","get_dte","fix_and_retry","emit_dte_again"],"description":"Qué le toca al llamante en este estado, en el vocabulario que el resto de la API ya usa."},"links":{"type":"object","properties":{"dte":{"type":"string"}},"required":["dte"],"description":"Presente solo cuando hay `result_ref`."}},"required":["id","status","kind","result_ref","rejection_reason","expires_at","resolved_at","created_at","next_action"]},"DteReference":{"type":"object","properties":{"line_num":{"type":"integer","minimum":1,"description":"`<NroLinRef>` del XML: identidad de la línea dentro del documento. Admite saltos."},"tipo_doc_ref":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Código SII del documento referenciado (correctiva) o el string original (comercial)."},"folio_ref":{"anyOf":[{"type":"integer"},{"type":"string"}]},"fecha_ref":{"type":"string","description":"`<FchRef>`: fecha del documento REFERENCIADO, no la de éste. Desambigua cuando el mismo (tipo, folio) existe en más de un período: el folio se reinicia por emisor y por ambiente."},"cod_ref":{"type":"integer","nullable":true,"description":"1 anula · 2 corrige texto · 3 corrige montos · null = referencia comercial"},"razon_ref":{"type":"string","nullable":true}},"required":["line_num","tipo_doc_ref","folio_ref","fecha_ref","cod_ref","razon_ref"]},"DteSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"folio":{"type":"integer"},"tipo_dte":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]},{"type":"number","enum":[110]},{"type":"number","enum":[112]}]},"rut_emisor":{"type":"string"},"rut_receptor":{"type":"string"},"razon_social_receptor":{"type":"string","description":"Razón social del receptor, tal como quedó en el documento emitido."},"monto_neto":{"type":"integer","description":"Monto neto afecto. 0 en un documento exento."},"monto_exento":{"type":"integer","description":"Monto exento del documento EN PESOS CHILENOS, siempre. 0 cuando no hay. En una exportación (110/112) NO es lo que declara la factura: el total exportado se registra aquí ya convertido, y el monto en su moneda viaja en `monto_moneda` con la moneda en `moneda_documento`. Vivía sólo en el DETALLE, así que cuadrar una exenta (34), o el exento de una 33 mixta, desde el listado costaba un `GET /dtes/{id}` por fila, que es el motivo por el que `monto_neto` e `iva` ya viajaban aquí."},"iva":{"type":"integer","description":"IVA del documento. 0 cuando no hay monto afecto."},"monto_total":{"type":"integer","description":"Total del documento EN PESOS CHILENOS, siempre: es lo que consumen el Libro de Ventas, las cuotas y el F29. En una exportación (110/112) es el EQUIVALENTE en pesos: lo que declara la factura viene en `monto_moneda`, y la moneda en `moneda_documento`."},"moneda_documento":{"type":"string","description":"Sólo en exportación (110/112): la moneda del documento, con la glosa del catálogo del SII (\"DOLAR USA\", \"EURO\"). Ausente en un documento en pesos, donde `monto_total` ya lo dice todo."},"monto_moneda":{"type":"number","description":"Sólo en exportación: el total EN la moneda del documento, con hasta 4 decimales. Es la cifra que dice la factura; `monto_total` es su equivalente en pesos al tipo de cambio del día."},"sii_status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"estado":{"$ref":"#/components/schemas/EstadoDte"},"sii_glosa":{"type":"string","nullable":true,"description":"Glosa del SII para `sii_status`. null mientras no haya respuesta."},"track_id":{"type":"integer","nullable":true,"description":"TrackID del envío al SII. null hasta que el DTE se sube."},"sii_env":{"type":"string","enum":["cert","prod"]},"sii_last_polled":{"type":"string","nullable":true,"description":"Última ESCRITURA de estado, no solo consultas al SII: se estampa tanto en cada poll (haya cambio o no) como en las transiciones de la emisión (`queued`, `sending`, `signed`). Un DTE recién emitido ya la trae. Nunca pierde un cambio; sí devuelve documentos cuyo estado no cambió. Es el ancla de `?polled_since=`."},"fecha_emision":{"type":"string"},"documento_disponible":{"type":"boolean","description":"`true` = hay XML firmado y `/dtes/{id}/pdf|xml|pdf-url` responden. Distingue “existe y se puede bajar” de “existe pero aún no está firmado”, sin gastar un request en un 409."},"created_at":{"type":"string"},"receptor_estado":{"type":"string","enum":["reclamado","aceptado","en_plazo","aceptado_tacito","sin_info"],"description":"Qué hizo TU CLIENTE con el documento. NO es `sii_status`: el SII puede haberlo aceptado (`EPR`) y el receptor reclamarlo igual: son dos máquinas de estado distintas. Se decide en este orden, el mismo que aplica el servidor: (1) `reclamado`: el receptor lo reclamó ante el SII; es un HECHO registrado y es IRREVERSIBLE: no existe forma de deshacerlo por esta API ni por el portal, y la salida comercial es emitir una nota de crédito. (2) `aceptado`: el receptor otorgó recibo, o el SII informó que el plazo se cumplió sin reclamo; también es un hecho registrado. (3) `en_plazo`: todavía corre la ventana, y cierra en el instante que indica `plazo_reclamo_cierra`. (4) `aceptado_tacito`: esa ventana ya cerró sin reclamo (Ley 19.983). (5) `sin_info`: el SII aún no informó `fecha_recepcion_sii`, así que el plazo no empezó a correr y no se sabe nada del receptor; NO significa que no haya respondido. Los tres últimos se DERIVAN contra el instante del request y cambian solos con el reloj: no los caches."},"receptor_reclamado_at":{"type":"string","nullable":true,"description":"`YYYY-MM-DD` del reclamo, tal como lo informa el registro del SII. `null` = no hay reclamo registrado, o el reclamo llegó sólo como código y sin su fecha (mira `receptor_estado`, que es el campo que decide). Un `null` aquí nunca significa por sí solo que el cliente no haya reclamado."},"receptor_acuse_at":{"type":"string","nullable":true,"description":"`YYYY-MM-DD` del acuse de recibo del receptor. `null` = no lo otorgó, o llegó sin fecha. Igual que su hermano, no es el campo con el que se decide: ése es `receptor_estado`."},"fecha_recepcion_sii":{"type":"string","nullable":true,"description":"Instante ISO-8601 (con hora) en que el SII recibió el documento y lo dejó a disposición del receptor. Es el ANCLA del plazo de reclamo: `fecha_emision` NO lo ancla, y contar desde ahí ya fechó un vencimiento cuatro días antes de tiempo. `null` = el SII todavía no lo informó (por eso el plazo no corre y `receptor_estado` vale `sin_info`); se puebla solo cuando el registro del SII lo entrega."},"plazo_reclamo_cierra":{"type":"string","nullable":true,"description":"Instante ISO-8601 EXACTO en que el receptor pierde el derecho a reclamar: `fecha_recepcion_sii` + 192 horas (Ley 19.983, Art. 3). Es una HORA, no un día de calendario: el SII cuenta fecha-hora a fecha-hora y a partir de ese instante rechaza el reclamo, así que tratar el día entero como disponible le regala al receptor horas que ya no tiene. `null` cuando no hay ancla (`fecha_recepcion_sii` en `null`): sin fecha de recepción no hay plazo que calcular, y una fecha derivada de `fecha_emision` sería sencillamente errónea. Este plazo corre contra el RECEPTOR; al emisor no le abre ninguna ventana ni le exige ninguna acción."},"references":{"type":"array","items":{"$ref":"#/components/schemas/DteReference"},"description":"`<Referencia>` del documento: correctivas (NC/ND) y comerciales (orden de compra…). Un documento sin referencias trae `[]`, nunca `null`."},"links":{"type":"object","properties":{"self":{"type":"string"}},"required":["self"]}},"required":["id","folio","tipo_dte","rut_emisor","rut_receptor","razon_social_receptor","monto_neto","monto_exento","iva","monto_total","sii_status","estado","sii_glosa","track_id","sii_env","sii_last_polled","fecha_emision","documento_disponible","created_at","receptor_estado","receptor_reclamado_at","receptor_acuse_at","fecha_recepcion_sii","plazo_reclamo_cierra","references","links"]},"DteListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DteSummary"}},"next_cursor":{"type":"string","nullable":true}},"required":["data","next_cursor"]},"DteDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"folio":{"type":"integer"},"tipo_dte":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]},{"type":"number","enum":[110]},{"type":"number","enum":[112]}]},"rut_emisor":{"type":"string"},"rut_receptor":{"type":"string"},"razon_social_receptor":{"type":"string","nullable":true},"giro_receptor":{"type":"string","nullable":true},"direccion_receptor":{"type":"string","nullable":true},"comuna_receptor":{"type":"string","nullable":true},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer","description":"Monto exento del documento EN PESOS CHILENOS, siempre. 0 cuando no hay. En una exportación (110/112) NO es lo que declara la factura: el total exportado se registra aquí ya convertido, y el monto en su moneda viaja en `monto_moneda` con la moneda en `moneda_documento`. Vivía sólo en el DETALLE, así que cuadrar una exenta (34), o el exento de una 33 mixta, desde el listado costaba un `GET /dtes/{id}` por fila, que es el motivo por el que `monto_neto` e `iva` ya viajaban aquí."},"iva":{"type":"integer"},"monto_total":{"type":"integer","description":"Total EN PESOS CHILENOS, siempre. En una exportación es el equivalente al tipo de cambio del día: la cifra que declara la factura está en `monto_moneda`."},"moneda_documento":{"type":"string","description":"Sólo exportación: glosa del catálogo del SII (\"DOLAR USA\")."},"monto_moneda":{"type":"number","description":"Sólo exportación: el total EN esa moneda, hasta 4 decimales."},"tipo_cambio":{"type":"number","nullable":true,"description":"Sólo exportación: con qué tipo de cambio se obtuvo `monto_total`. Lo resuelve el SERVIDOR el día de la emisión, nunca el `tpo_cambio` que venga en el body."},"tipo_cambio_fuente":{"type":"string","nullable":true,"description":"Sólo exportación: de dónde salió ese tipo de cambio, para poder auditarlo."},"sii_env":{"type":"string","enum":["cert","prod"]},"sii_status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"estado":{"$ref":"#/components/schemas/EstadoDte"},"sii_glosa":{"type":"string","nullable":true},"track_id":{"type":"integer","nullable":true},"sii_last_polled":{"type":"string","nullable":true,"description":"Última ESCRITURA de estado (no sólo consultas al SII: también las transiciones de la emisión). null si nunca se escribió."},"fecha_emision":{"type":"string"},"created_at":{"type":"string"},"receptor_estado":{"type":"string","enum":["reclamado","aceptado","en_plazo","aceptado_tacito","sin_info"],"description":"Qué hizo TU CLIENTE con el documento. NO es `sii_status`: el SII puede haberlo aceptado (`EPR`) y el receptor reclamarlo igual: son dos máquinas de estado distintas. Se decide en este orden, el mismo que aplica el servidor: (1) `reclamado`: el receptor lo reclamó ante el SII; es un HECHO registrado y es IRREVERSIBLE: no existe forma de deshacerlo por esta API ni por el portal, y la salida comercial es emitir una nota de crédito. (2) `aceptado`: el receptor otorgó recibo, o el SII informó que el plazo se cumplió sin reclamo; también es un hecho registrado. (3) `en_plazo`: todavía corre la ventana, y cierra en el instante que indica `plazo_reclamo_cierra`. (4) `aceptado_tacito`: esa ventana ya cerró sin reclamo (Ley 19.983). (5) `sin_info`: el SII aún no informó `fecha_recepcion_sii`, así que el plazo no empezó a correr y no se sabe nada del receptor; NO significa que no haya respondido. Los tres últimos se DERIVAN contra el instante del request y cambian solos con el reloj: no los caches."},"receptor_reclamado_at":{"type":"string","nullable":true,"description":"`YYYY-MM-DD` del reclamo, tal como lo informa el registro del SII. `null` = no hay reclamo registrado, o el reclamo llegó sólo como código y sin su fecha (mira `receptor_estado`, que es el campo que decide). Un `null` aquí nunca significa por sí solo que el cliente no haya reclamado."},"receptor_acuse_at":{"type":"string","nullable":true,"description":"`YYYY-MM-DD` del acuse de recibo del receptor. `null` = no lo otorgó, o llegó sin fecha. Igual que su hermano, no es el campo con el que se decide: ése es `receptor_estado`."},"fecha_recepcion_sii":{"type":"string","nullable":true,"description":"Instante ISO-8601 (con hora) en que el SII recibió el documento y lo dejó a disposición del receptor. Es el ANCLA del plazo de reclamo: `fecha_emision` NO lo ancla, y contar desde ahí ya fechó un vencimiento cuatro días antes de tiempo. `null` = el SII todavía no lo informó (por eso el plazo no corre y `receptor_estado` vale `sin_info`); se puebla solo cuando el registro del SII lo entrega."},"plazo_reclamo_cierra":{"type":"string","nullable":true,"description":"Instante ISO-8601 EXACTO en que el receptor pierde el derecho a reclamar: `fecha_recepcion_sii` + 192 horas (Ley 19.983, Art. 3). Es una HORA, no un día de calendario: el SII cuenta fecha-hora a fecha-hora y a partir de ese instante rechaza el reclamo, así que tratar el día entero como disponible le regala al receptor horas que ya no tiene. `null` cuando no hay ancla (`fecha_recepcion_sii` en `null`): sin fecha de recepción no hay plazo que calcular, y una fecha derivada de `fecha_emision` sería sencillamente errónea. Este plazo corre contra el RECEPTOR; al emisor no le abre ninguna ventana ni le exige ninguna acción."},"items":{"type":"array","items":{"type":"object","properties":{"position":{"type":"integer"},"nombre":{"type":"string"},"descripcion":{"type":"string","nullable":true},"cantidad":{"type":"number","nullable":true,"description":"Cantidad (SII QtyItem). null si el documento NO la declara: el XSD la permite ausente (una NC con CodRef=2, o un documento importado del respaldo del SII). null NO significa cero."},"unidad":{"type":"string","nullable":true,"description":"Unidad de medida (SII UnmdItem); null si no se declaró"},"descuento_pct":{"type":"number","nullable":true,"description":"Descuento por línea (SII DescuentoPct, %); null si no aplica"},"codigos":{"type":"array","nullable":true,"items":{"type":"object","properties":{"tipo":{"type":"string"},"valor":{"type":"string"}},"required":["tipo","valor"]},"description":"Códigos de ítem (SII CdgItem: {tipo→TpoCodigo, valor→VlrCodigo}, hasta 5); null si no aplica"},"precio_unitario":{"type":"number","nullable":true,"description":"Precio unitario (SII PrcItem). null si el documento no lo declara; no es cero."},"monto_item":{"type":"integer"},"exento":{"type":"boolean"}},"required":["position","nombre","descripcion","cantidad","unidad","descuento_pct","codigos","precio_unitario","monto_item","exento"]}},"status_history":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"at":{"type":"string","description":"ISO-8601 del momento observado"},"source":{"type":"string","enum":["local","sii"],"description":"Origen: transición local del pipeline o estado reportado por el SII"}},"required":["status","at","source"]},"description":"Historia cronológica de transiciones de estado del documento. Es el mismo rastro que sirve `GET /dtes/{id}/events`, sin la glosa: úsalo para ver por dónde pasó (p. ej. `-11 → EPR`) sin un request más."},"references":{"type":"array","items":{"$ref":"#/components/schemas/DteReference"},"description":"`<Referencia>` del documento: correctivas (NC/ND) y comerciales (orden de compra…). Un documento sin referencias trae `[]`, nunca `null`."},"correo_receptor":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Direcciones del receptor capturadas en la emisión. null/vacío = no se envía."},"envio_estado":{"type":"string","enum":["pendiente","enviado","sin_correo","fallido","omitido","no_aplica_cert","no_aplica_import"],"description":"Estado del CORREO al receptor. NO es el estado ante el SII (ese es `sii_status`). `no_aplica_import` = el documento entró por el Respaldo del SII: lo emitió y lo entregó el sistema anterior, así que no hay envío nuestro que hacer y `POST /dtes/{id}/resend-delivery` lo rechaza. `no_aplica_cert` = en certificación, la única dirección era la casilla de intercambio del padrón, que no recibe documentos de prueba. Ninguno de los dos es un fallo."},"envio_message_id":{"type":"string","nullable":true},"enviado_at":{"type":"string","nullable":true},"envio_destinatarios":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Registro del `to:` efectivo del envío. Sólo lectura: no son direcciones reutilizables."},"envio_casilla_intercambio":{"type":"string","nullable":true,"description":"Cuál de los destinatarios la aportó la casilla de intercambio del padrón del SII."},"anulado_estado":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]},{"nullable":true}],"description":"1 = anulada antes de enviar al SII · 2 = después · null = guía viva (o no es un 52)."},"anulado_at":{"type":"string","nullable":true},"anulado_motivo":{"type":"string","nullable":true},"links":{"type":"object","properties":{"self":{"type":"string"},"pdf":{"type":"string"},"xml":{"type":"string"},"events":{"type":"string"}},"required":["self","pdf","xml","events"]}},"required":["id","folio","tipo_dte","rut_emisor","rut_receptor","razon_social_receptor","giro_receptor","direccion_receptor","comuna_receptor","monto_neto","monto_exento","iva","monto_total","sii_env","sii_status","estado","sii_glosa","track_id","sii_last_polled","fecha_emision","created_at","receptor_estado","receptor_reclamado_at","receptor_acuse_at","fecha_recepcion_sii","plazo_reclamo_cierra","items","status_history","references","correo_receptor","envio_estado","envio_message_id","enviado_at","envio_destinatarios","envio_casilla_intercambio","anulado_estado","anulado_at","anulado_motivo","links"]},"DteTotalsRow":{"type":"object","properties":{"tipo_dte":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]},{"type":"number","enum":[110]},{"type":"number","enum":[112]}]},"sii_status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"cantidad":{"type":"integer"},"monto_neto":{"type":"number"},"monto_exento":{"type":"number"},"iva":{"type":"number"},"monto_total":{"type":"number"}},"required":["tipo_dte","sii_status","cantidad","monto_neto","monto_exento","iva","monto_total"]},"DteTotalsResponse":{"type":"object","properties":{"periodo":{"type":"string","description":"YYYY-MM del período agregado"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DteTotalsRow"}}},"required":["periodo","data"]},"DteRefreshAccepted":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["refresh_enqueued"]},"estado":{"$ref":"#/components/schemas/EstadoDte"}},"required":["id","status","estado"]},"DteRefreshNotEnqueued":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["already_terminal","poll_in_progress"],"description":"`already_terminal` = el SII ya dio su veredicto y no hay nada que reconsultar. `poll_in_progress` = hay un poll durable vivo; reintentar no lo acelera."},"sii_status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Vocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"estado":{"$ref":"#/components/schemas/EstadoDte"},"sii_glosa":{"type":"string","nullable":true,"description":"Motivo que reportó el SII. Presente SOLO en `already_terminal`: sin esto, un `already_terminal` sobre un `RCH` es un 200 sin una sola pista de que el documento fracasó."},"retry_after":{"type":"integer","description":"Segundos a esperar antes de que valga la pena volver a llamar. Presente SOLO en `poll_in_progress`, derivado de la ventana en que se presume vivo el poll durable (25 h). Sin este número, un 200 que dice 'no encolé nada' invita justo al bucle que vino a cortar."},"sii_last_polled":{"type":"string","format":"date-time"}},"required":["id","status","sii_status","estado"]},"DteEventsFeed":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string","enum":["queued","sending","awaiting_sii","SOK","CRT","FOK","PDR","PRD","-11","EPR","RPR","aceptado_con_reparos","RFR","RCT","RSC","RCH","stuck","signed","accepted","sin_permiso_sii"],"description":"Estado en esta transición.\n\nVocabulario de `dtes.sii_status`, generado del catálogo de estados. Cada valor con su glosa, si tiene VEREDICTO del SII (`terminal`) y la acción sugerida. La descripción larga de cada uno viaja en el bloque `estado` de esta misma respuesta:\n\n`queued`: en cola · terminal: no · acción: `esperar`\n`sending`: enviando · terminal: no · acción: `esperar`\n`signed`: firmado, sin subir al SII · terminal: no · acción: `esperar`\n`awaiting_sii`: esperando al SII · terminal: no · acción: `esperar` · DEPRECADO\n`SOK`: schema del envío validado · terminal: no · acción: `esperar`\n`CRT`: carátula del envío validada · terminal: no · acción: `esperar`\n`FOK`: firma del envío validada · terminal: no · acción: `esperar`\n`PDR`: envío en proceso · terminal: no · acción: `esperar`\n`PRD`: envío en proceso · terminal: no · acción: `esperar`\n`-11`: procesando en el SII · terminal: no · acción: `esperar`\n`EPR`: aceptado · terminal: sí · acción: `ninguna`\n`RPR`: aceptado con reparos · terminal: sí · acción: `ninguna`\n`aceptado_con_reparos`: aceptado con reparos · terminal: sí · acción: `ninguna` · DEPRECADO\n`accepted`: aceptado (importado del Respaldo del SII) · terminal: sí · acción: `ninguna`\n`RFR`: rechazo por firma · terminal: sí · acción: `contactar_soporte`\n`RCT`: rechazo por carátula · terminal: sí · acción: `contactar_soporte`\n`RSC`: rechazo por schema · terminal: sí · acción: `contactar_soporte`\n`RCH`: documento rechazado · terminal: sí · acción: `reemitir`\n`stuck`: atascado en SII · terminal: no · acción: `reintentar_consulta`\n`sin_permiso_sii`: sin permiso para consultar en el SII · terminal: no · acción: `accion_en_sii`\n\nCorta cualquier bucle de espera por `estado.terminal`, NUNCA por `sii_status === \"EPR\"`: un rechazo (`RFR`, `RCT`, `RSC` y `RCH`) también es final, y ese bucle no saldría nunca. `stuck` y `sin_permiso_sii` no son terminales (el SII no llegó a juzgar el documento) pero tampoco avanzan solos: los destraba `POST /dtes/{id}/refresh-status`."},"at":{"type":"string","description":"ISO-8601 del momento observado"},"source":{"type":"string","enum":["local","sii"],"description":"Origen: transición local o estado reportado por el SII"},"glosa":{"type":"string","nullable":true,"description":"Motivo que reporta el SII (rechazo/reparo); null si no aplica"}},"required":["status","at","source","glosa"]}},"links":{"type":"object","properties":{"self":{"type":"string"},"dte":{"type":"string"}},"required":["self","dte"]}},"required":["data","links"]},"DtePdfUrlResponse":{"type":"object","properties":{"url":{"type":"string","description":"Enlace-capacidad de un solo documento (`https://app.notta.cl/d/<token>`). Sirve el PDF SIN sesión ni Bearer: el token es la credencial. Vence a los 15 minutos (D12)."},"expires_at":{"type":"string","description":"Vencimiento del enlace, ISO 8601."}},"required":["url","expires_at"]},"GuiaAnularInput":{"type":"object","properties":{"motivo":{"type":"string","minLength":1,"maxLength":250}},"required":["motivo"]},"DteAnularResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"anuladoEstado":{"anyOf":[{"type":"number","enum":[1]},{"type":"number","enum":[2]}],"description":"Estado <Anulado> del Libro de Guías: 1 = anulada antes de enviar al SII, 2 = después."}},"required":["id","anuladoEstado"]}},"required":["data"]},"DteMuestrasSendResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"sent":{"type":"integer","description":"Cantidad de PDFs de muestra adjuntados en el correo al SII"},"sentAt":{"type":"string","description":"ISO timestamp persistido en metadata.muestras.sentAt"}},"required":["sent","sentAt"]}},"required":["data"]},"CafUploadInput":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"XML CAF descargado del SII (rango de folios)"},"tipo_esperado":{"type":"integer","nullable":true,"description":"Si se envía, rechaza el upload cuando el tipo del CAF no coincide (caf.wrong_tipo)"},"certificate_id":{"type":"string","format":"uuid","description":"Default: el primer certificado activo del org"}},"required":["file"]},"CafUploadResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tipo_dte":{"type":"integer"},"folio_desde":{"type":"integer"},"folio_hasta":{"type":"integer"},"remaining":{"type":"integer"},"low_folios":{"type":"boolean"}},"required":["id","tipo_dte","folio_desde","folio_hasta","remaining","low_folios"]}},"required":["data"]},"CafListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"rut_emisor":{"type":"string"},"tipo_dte":{"type":"integer"},"folio_desde":{"type":"integer"},"folio_hasta":{"type":"integer"},"next_folio":{"type":"integer"},"remaining":{"type":"integer"},"low_folios":{"type":"boolean"},"not_after":{"type":"string"},"exhausted":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","rut_emisor","tipo_dte","folio_desde","folio_hasta","next_folio","remaining","low_folios","not_after","exhausted","created_at"]}}},"required":["data"]},"CafDeleteResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"},"dtes_deleted":{"type":"integer"}},"required":["id","deleted","dtes_deleted"]}},"required":["data"]},"CafRequestInput":{"type":"object","properties":{"tipo":{"type":"integer","description":"Tipo DTE a timbrar. Uno de: 33, 34, 46, 52, 56, 61, 110, 112 (NO boletas 39/41: pipeline REST propio).","example":33},"cantidad":{"type":"integer","minimum":1,"maximum":1000,"description":"Override opcional de la cantidad de folios a solicitar (default por-tipo). 1–1000."}},"required":["tipo"]},"CafRequestResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"requested":{"type":"boolean","description":"true si se solicitó un rango nuevo al SII"},"reason":{"type":"string","description":"p.ej. no_cafs_missing cuando ya hay folios suficientes y no se pidió nada"},"cafs":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"integer"},"estado":{"type":"string","description":"requested | cooldown | prod_not_certified | rejected | …"}},"required":["tipo","estado"]}}},"required":["requested","cafs"]}},"required":["data"]},"CertificateUploadInput":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Certificado digital .p12/.pfx"},"password":{"type":"string","description":"Contraseña del .p12: se cifra junto al blob (KMS per-org)"},"label":{"type":"string"},"rut_owner":{"type":"string","description":"RUT del titular del certificado (BODY-DV)"},"subject_cn":{"type":"string"},"issuer_cn":{"type":"string"}},"required":["file","password","label"]},"CertificateUploadResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Usalo como header X-Cert-Id en /dtes"},"label":{"type":"string"},"not_after":{"type":"string"}},"required":["id","label","not_after"]}},"required":["data"]},"CertificateListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":"string"},"rut_owner":{"type":"string"},"subject_cn":{"type":"string"},"not_before":{"type":"string"},"not_after":{"type":"string"},"created_at":{"type":"string"}},"required":["id","label","rut_owner","subject_cn","not_before","not_after","created_at"]}}},"required":["data"]},"CertificateDeleteResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}},"required":["id","deleted"]}},"required":["data"]},"ProfileResponse":{"type":"object","properties":{"giro":{"type":"string","minLength":1,"maxLength":80},"direccion":{"type":"string","minLength":1,"maxLength":70},"comuna":{"type":"string","minLength":1,"maxLength":20},"actividadEconomica":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"description":"Perfil del emisor tal como se persiste: todos los campos son opcionales."},"SiiCertStateResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"journey":{"type":"object","additionalProperties":{"nullable":true},"description":"Journey de certificación derivado del snapshot scrapeado."},"scrapedAt":{"type":"string","nullable":true,"description":"ISO del último scrape, o null si nunca se scrapeó."}},"required":["journey","scrapedAt"]}},"required":["data"]},"SiiReadinessResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"ok":{"type":"boolean","description":"true si la certificación SII está completa."},"postulationStep":{"type":"string"},"currentPhase":{"type":"string"},"certSubStates":{"type":"object","additionalProperties":{"nullable":true}}},"required":["ok","postulationStep","currentPhase","certSubStates"]}},"required":["data"]},"SiiRecentDocumentsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Últimas ventas 33/34 de la org (máx 50), env-scopeadas por `api_keys.sii_env` (Bearer) o la cookie de env (browser)."}},"required":["data"]},"SiiDocumentTemplateResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"tipo_dte":{"type":"number","example":33},"receptor":{"type":"object","properties":{"rut":{"type":"string"},"razon":{"type":"string"}},"required":["rut","razon"]},"items":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}},"required":["tipo_dte","receptor","items"]}},"required":["data"]},"SetPruebasEnvelope":{"type":"object","properties":{"data":{"type":"object","additionalProperties":{"nullable":true}}},"required":["data"],"description":"Envelope { data } del pipeline Set de Pruebas: shape interno rico, ver route handlers."},"RcofSendInput":{"type":"object","properties":{"fecha":{"type":"string","description":"YYYY-MM-DD, requerido (rcof.fecha_required si falta/vacío)"}},"required":["fecha"]},"RcofSendAccepted":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"fecha":{"type":"string"},"sec_envio":{"type":"integer","description":"Incrementa por cada reenvío/corrección del mismo día"},"status":{"type":"string","enum":["queued"]}},"required":["ok","fecha","sec_envio","status"]},"RcofEnvioSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fecha":{"type":"string"},"sec_envio":{"type":"integer"},"estado":{"type":"string","enum":["queued","EPR","DOK","RPR","aceptado_con_reparos","RFR","RCT","RSC","error"],"description":"Lifecycle real: queued → EPR → terminal (DOK|RPR|aceptado_con_reparos|RFR|RCT|RSC|error)"},"track_id":{"type":"string","nullable":true},"sii_glosa":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","fecha","sec_envio","estado","track_id","sii_glosa","created_at"]},"RcofListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RcofEnvioSummary"}}},"required":["data"]},"RcofDetailResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fecha":{"type":"string"},"sec_envio":{"type":"integer"},"estado":{"type":"string","enum":["queued","EPR","DOK","RPR","aceptado_con_reparos","RFR","RCT","RSC","error"],"description":"Lifecycle real: queued → EPR → terminal (DOK|RPR|aceptado_con_reparos|RFR|RCT|RSC|error)"},"track_id":{"type":"string","nullable":true},"sii_glosa":{"type":"string","nullable":true},"summary":{"type":"object","nullable":true,"properties":{"orgId":{"type":"string","format":"uuid"},"fecha":{"type":"string"},"resumenes":{"type":"array","items":{"type":"object","properties":{"tipoDocumento":{"anyOf":[{"type":"number","enum":[39]},{"type":"number","enum":[41]}]},"mntNeto":{"type":"integer"},"mntIva":{"type":"integer"},"mntExento":{"type":"integer"},"mntTotal":{"type":"integer"},"foliosEmitidos":{"type":"integer"},"foliosAnulados":{"type":"integer"},"foliosUtilizados":{"type":"integer"},"rangoUtilizados":{"type":"array","items":{"type":"object","properties":{"inicial":{"type":"integer"},"final":{"type":"integer"}},"required":["inicial","final"]}},"rangoAnulados":{"type":"array","items":{"type":"object","properties":{"inicial":{"type":"integer"},"final":{"type":"integer"}},"required":["inicial","final"]}}},"required":["tipoDocumento","mntNeto","mntIva","mntExento","mntTotal","foliosEmitidos","foliosAnulados","foliosUtilizados","rangoUtilizados","rangoAnulados"]}}},"required":["orgId","fecha","resumenes"],"description":"JSONB persistido tal cual al crear el envío (camelCase, sin re-serializar)"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","fecha","sec_envio","estado","track_id","sii_glosa","summary","created_at","updated_at"]}},"required":["data"]},"ReadinessResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"phase":{"type":"string"},"siiStep":{"type":"string"},"targetTypes":{"type":"array","items":{"type":"integer"}},"assignedUnsupported":{"type":"array","items":{"type":"integer"}},"items":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"status":{"type":"string","enum":["ready","missing","blocked","pending"]},"detail":{"type":"string"},"cta":{"type":"object","properties":{"label":{"type":"string"},"href":{"type":"string"}},"required":["label","href"]}},"required":["key","label","status"]}},"complete":{"type":"boolean"}},"required":["phase","siiStep","targetTypes","assignedUnsupported","items","complete"]}},"required":["data"]},"RcvSyncInput":{"type":"object","properties":{"periodo":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"type":{"type":"string","enum":["received","issued","both"],"default":"both"},"rut":{"type":"string","minLength":1},"force":{"type":"boolean"}},"required":["periodo","rut"]},"RcvSyncAccepted":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"uuid"},"from_cache":{"type":"boolean"}},"required":["snapshot_id","from_cache"]},"RcvSnapshot":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"rut":{"type":"string"},"period":{"type":"string"},"period_year":{"type":"integer"},"period_month":{"type":"integer"},"type":{"type":"string","enum":["received","issued","both"]},"record_count":{"type":"integer"},"source":{"type":"string"},"sii_env":{"type":"string","enum":["cert","prod"]},"parsed_json":{"nullable":true,"description":"Payload RCV parseado, forma varía por type"},"synced_at":{"type":"string"},"created_at":{"type":"string"}},"required":["id","rut","period","period_year","period_month","type","record_count","source","sii_env","synced_at","created_at"]},"RcvListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RcvSnapshot"}}},"required":["data"]},"RcvDocumentRow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["issued","received"]},"period":{"type":"string","description":"YYYY-MM"},"document_type":{"type":"integer","description":"Código SII del tipo (33, 34, 39, 46, 52, 56, 61…)"},"folio":{"type":"integer"},"issuer_rut":{"type":"string"},"issuer_name":{"type":"string","nullable":true},"receiver_rut":{"type":"string"},"receiver_name":{"type":"string","nullable":true},"issued_at":{"type":"string","nullable":true,"description":"YYYY-MM-DD normalizado (el SII manda DD/MM/YYYY)"},"received_at":{"type":"string","nullable":true,"description":"YYYY-MM-DD; ancla del plazo de reclamo en compras"},"net_amount":{"type":"integer"},"exempt_amount":{"type":"integer"},"vat_amount":{"type":"integer"},"total_amount":{"type":"integer","description":"El total del documento según el SII. Es el único monto que siempre cierra: en documentos con retención o impuestos adicionales (p. ej. Factura de Compra 46) `neto + exento + IVA` NO suma el total, porque esos tributos no tienen columna propia acá."},"currency":{"type":"string"},"estado":{"type":"string","enum":["registro","pendiente","no_incluir","reclamado"],"description":"Sección del registro del SII en la que está el documento."},"evento_receptor":{"type":"string","nullable":true,"description":"Código del evento del receptor tal como lo devuelve el detalle del RCV. Los que el registro manda de verdad son de UNA letra: `R` (reclamado por el receptor), `C` (recibo otorgado por el receptor), `A` (no reclamado en plazo, o sea la aceptación tácita ya consumada) y `P`, que **no** es un evento del receptor sino la forma de pago (contado): el campo del SII viene sobrecargado, y tratar `P` como respuesta del cliente es un error. `null` = el registro no informó ninguno. Se sirve el código y no solo la glosa porque la glosa es texto libre del SII."},"evento_receptor_glosa":{"type":"string","nullable":true},"reclamado_at":{"type":"string","nullable":true},"acuse_at":{"type":"string","nullable":true},"referencia_tipo":{"type":"integer","nullable":true,"description":"Tipo del documento al que ESTA fila hace referencia, sea cual sea su `document_type`. `null` = no referencia a ninguno. NO equivale a «este documento corrige a otro»: una factura también referencia, y de hecho lo hace (en producción, facturas 33 que apuntan a la guía 52 que consolidan, o a documentos de papel 30/48/50). Para saber si es una corrección mira `document_type`: solo 56 y 61 corrigen. Y no asumas 33 en el referenciado: hay referencias reales a 34 (exenta), 39 (boleta) y 61 (otra NC); enlazar solo por folio, sin el tipo, cruza secuencias distintas."},"referencia_folio":{"type":"integer","nullable":true},"sii_env":{"type":"string","enum":["cert","prod"]},"dte_id":{"type":"string","nullable":true,"format":"uuid","description":"Id del DTE en Notta cuando este documento también existe acá (solo ventas). `null` = la fila vive SOLO en el registro del SII, que guarda el asiento y no el documento."},"documento_disponible":{"type":"boolean","description":"`true` = hay XML firmado y `/dtes/{dte_id}/pdf|xml|pdf-url` responden. Distingue “existe y se puede bajar” de “existe pero aún no está firmado”, sin gastar un request en un 409."}},"required":["id","type","period","document_type","folio","issuer_rut","issuer_name","receiver_rut","receiver_name","issued_at","received_at","net_amount","exempt_amount","vat_amount","total_amount","currency","estado","evento_receptor","evento_receptor_glosa","reclamado_at","acuse_at","referencia_tipo","referencia_folio","sii_env","dte_id","documento_disponible"]},"RecepcionRow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emisorRut":{"type":"string"},"emisorNombre":{"type":"string","nullable":true},"tipoDte":{"type":"integer"},"folio":{"type":"integer"},"montoTotal":{"type":"number"},"fechaEmision":{"type":"string","description":"FchEmis YYYY-MM-DD. **NO ancla el plazo**: decía lo contrario hasta el 2026-08-13 y de ahí salían vencimientos calculados 4 días antes de tiempo. El plazo lo ancla `receivedAt`."},"receivedAt":{"type":"string","description":"Cuándo recibió el documento el SII. **Es el ancla del plazo**: la Circular N° 4 (11-01-2017) es literal (los 8 días corren *\"desde la fecha en que el respectivo documento sea recibido por el Servicio de Impuestos Internos\"*), no desde la emisión. Un proveedor que envía tarde no le acorta el plazo al receptor. En filas `origen='intercambio'` es cuándo llegó el sobre a la Casilla de Intercambio. **Es un día, y el Servicio cuenta fecha-hora a fecha-hora**: la ventana cierra a las 192 horas del INSTANTE de recepción, que puede caer hasta 28 horas después de la medianoche de este día. Para saber cuánto queda usa `diasRestantes`, que ya cuenta sobre ese instante; `receivedAt + 8 días` da de menos."},"estadoRecepcion":{"type":"string","description":"Carril de INTERCAMBIO con el emisor. Hoy nadie lo escribe, así que se queda en `PENDIENTE`: no es el estado del documento ante el SII: ese lo mandan `rarEventos` y, en las solo-RCV, `rcvEstado`. En `origen='rcv'` vale `RCV`, un relleno sin significado (esas filas no tienen carril de intercambio)."},"acuseEnvio":{"type":"boolean"},"acuseTacito":{"type":"boolean"},"diasRestantes":{"type":"integer","description":"Días que quedan del plazo de 8 corridos (Ley 19.983/20.956), contados **desde `receivedAt`** (la recepción del SII) y no desde la emisión, sobre la fecha-**hora** exacta en que el Servicio recibió el documento. Es el número autoritativo: no lo recalcules desde `receivedAt`, que es solo el día. 0 o negativo = vencido: el acuse operó por ley y el reclamo ya no procede. Vencer NO hace perder el crédito de IVA, solo fija el período al que se imputa."},"rarEventos":{"type":"array","items":{"type":"string"},"description":"Códigos ya registrados en el Registro de Aceptación o Reclamos del SII"},"puedeAcusar":{"type":"boolean","description":"ERM (acuse de recibo) todavía registrable ante el SII. Es lo único que habilita el crédito de IVA. Una compra `origen='rcv'` SÍ se puede acusar aunque no tengamos el XML: al Servicio le basta el RUT del emisor, el tipo y el folio. Cuando viene en `false`, el motivo está en `motivoNoAccionable`."},"puedeAceptar":{"type":"boolean","description":"ACD (acepta contenido) todavía registrable. **Siempre `false` en `origen='rcv'`**: es irreversible y exige haber leído el documento, que en esas filas no tenemos. Además el ACD no da crédito de IVA."},"puedeReclamar":{"type":"boolean","description":"RCD/RFP/RFT todavía registrables. **Siempre `false` en `origen='rcv'`**: reclamar es irreversible y exige haber leído el documento. Quien necesite reclamar una de esas lo hace en el portal del SII, donde sí puede verla antes."},"accionable":{"type":"boolean"},"motivoNoAccionable":{"type":"object","nullable":true,"properties":{"codigo":{"type":"string","enum":["archivo_historico","evento_ya_registrado","tipo_no_registrable","ya_asentada_en_el_sii","ya_reclamada","excluida_del_registro","pago_contado","entrega_gratuita","acuse_tacito","ya_respondida","fuera_de_plazo"],"description":"Estable y comparable: es el contrato."},"glosa":{"type":"string","description":"Explicación en español, lista para mostrar o citar."}},"required":["codigo","glosa"],"description":"POR QUÉ no hay acción, cuando `accionable` es `false`; `null` cuando sí la hay. Existe porque un booleano en `false` sin motivo lo completa el consumidor: un agente recibió las tres banderas en `false` y explicó que Notta solo puede acusar si llegó el XML por casilla (falso) y lo convirtió en una recomendación. Usa este campo en vez de inferir la causa."},"fmaPago":{"type":"number","nullable":true,"description":"1=Contado, 2=Crédito, 3=Sin costo; null si no informado"},"tienePdf":{"type":"boolean"},"origen":{"type":"string","enum":["intercambio","rcv"]},"rcvEstado":{"type":"string","enum":["registro","pendiente","no_incluir","reclamado"]},"esArchivo":{"type":"boolean","description":"true = viene del Respaldo del SII, archivo histórico de solo lectura"},"siiEnv":{"type":"string","enum":["cert","prod"],"description":"Ambiente SII del documento (derivado del NroResol del sobre), solo en filas origen='intercambio'. Ausente en las solo-RCV. La lista ya viene acotada al ambiente de tu credencial."}},"required":["id","emisorRut","emisorNombre","tipoDte","folio","montoTotal","fechaEmision","receivedAt","estadoRecepcion","acuseEnvio","acuseTacito","diasRestantes","rarEventos","puedeAcusar","puedeAceptar","puedeReclamar","accionable","motivoNoAccionable","fmaPago","tienePdf","origen","esArchivo"]},"RecepcionListResponse":{"type":"object","properties":{"documentos":{"type":"array","items":{"$ref":"#/components/schemas/RecepcionRow"}},"total":{"type":"integer","description":"Total de filas que calzan el filtro (search incluido), no el tamaño de esta página"}},"required":["documentos","total"]},"RecepcionEventoBody":{"type":"object","properties":{"accion":{"type":"string","enum":["ERM","ACD","RCD","RFP","RFT"],"description":"ERM = acuse de recibo de mercaderías o servicios · ACD = acepta el contenido · RCD = reclamo al contenido · RFP = reclamo por falta parcial de mercaderías · RFT = reclamo por falta total. Un acuse y un reclamo son EXCLUYENTES entre sí: la única combinación válida es ACD + ERM."},"cedidaOverride":{"type":"boolean","description":"Reclamar un documento que el proveedor ya cedió a factoring. Renuncia a una protección legal (doctrina Corte Suprema 2025: la nota de crédito posterior es inoponible al cesionario, o sea que la empresa le sigue debiendo al factoring). Pedido por un agente (MCP) lo aprueba una persona antes de ejecutarse; con una API key clásica se ejecuta en el mismo request, igual que el resto de este endpoint."}},"required":["accion"]},"RecepcionEventoPendingResponse":{"type":"object","properties":{"status":{"type":"string","enum":["pending"]},"pending_id":{"type":"string","format":"uuid"},"approve_url":{"type":"string","description":"Pantalla donde una persona de la empresa lo aprueba o rechaza"},"expires_at":{"type":"string","description":"A las 24 h expira sin registrar nada"},"reason":{"type":"string"}},"required":["status","pending_id","approve_url","expires_at","reason"]},"SuggestedTypesResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"catalog":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"integer"},"label":{"type":"string"},"preselected":{"type":"boolean"}},"required":["tipo","label","preselected"]}},"assignedUnsupported":{"type":"array","items":{"type":"object","properties":{"tipo":{"type":"integer"},"label":{"type":"string"}},"required":["tipo","label"]}},"hasPostulation":{"type":"boolean"}},"required":["catalog","assignedUnsupported","hasPostulation"]}},"required":["data"]},"TargetTypesResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"tipos":{"type":"array","items":{"type":"integer"}}},"required":["tipos"]}},"required":["data"]},"BillingPlanStatus":{"type":"object","properties":{"planId":{"type":"string","enum":["free","starter","growth","pro","enterprise"]},"usedThisMonth":{"type":"integer","description":"Documentos (DTE+BHE) usados este mes en prod."},"limit":{"type":"integer","description":"Cupo mensual del plan activo (o free si no hay suscripción)."}},"required":["planId","usedThisMonth","limit"]},"BillingSubscribeInput":{"type":"object","properties":{"planId":{"type":"string","enum":["free","starter","growth","pro","enterprise"]},"idempotencyKey":{"type":"string","minLength":8,"maxLength":128},"paymentMethod":{"type":"object","properties":{"type":{"type":"string","enum":["mercadopago"]},"mp_payer_email":{"type":"string","minLength":1,"maxLength":200,"format":"email"},"card_token":{"type":"string","minLength":1,"maxLength":200},"payment_method_id":{"type":"string","minLength":1,"maxLength":50}},"required":["type","mp_payer_email"]}},"required":["planId","paymentMethod"]},"BillingSubscribeResult":{"type":"object","properties":{"subscriptionId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","trial"]}},"required":["subscriptionId","status"]},"WebhookEndpointPublic":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"sii_env":{"type":"string","enum":["cert","prod"],"description":"Ambiente de la suscripción. Sale de la API key que la creó, no del cuerpo: una key de certificación nunca recibe documentos de producción, y al revés."},"active":{"type":"boolean"},"created_at":{"type":"string"},"disabled_at":{"type":"string","nullable":true},"disabled_reason":{"type":"string","nullable":true,"description":"Por qué se apagó. Si `active` es false y esto trae texto, dejaste de recibir eventos."}},"required":["id","url","events","sii_env","active","created_at","disabled_at","disabled_reason"]},"WebhookCreated":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpointPublic"},{"type":"object","properties":{"secret":{"type":"string","description":"El signing secret, visible UNA sola vez. Guárdalo en tu gestor de secretos ahora: no se puede recuperar después, sólo rotar con `POST /webhooks/{id}/rotate-secret`."}},"required":["secret"]}]},"WebhookList":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpointPublic"}}},"required":["webhooks"]},"WebhookTestAccepted":{"type":"object","properties":{"delivery_id":{"type":"string","format":"uuid"},"event_id":{"type":"string","example":"evt_0195…"},"status":{"type":"string","example":"pending"}},"required":["delivery_id","event_id","status"]},"CreateWebhookInput":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["dte.emitted","dte.status_changed","dte.accepted","dte.rejected"]},"minItems":1}},"required":["url","events"]}},"parameters":{}},"paths":{"/dtes":{"post":{"operationId":"emitDte","security":[{"bearerAuth":["dte:write"]}],"tags":["dtes"],"summary":"Emitir DTE (33/34/46/52/56/61/110/112)","description":"Encola la emisión (firma + upload SII) y responde 202 con el folio asignado. Por una conexión MCP el 202 puede traer, en cambio, `{ status: 'pending', pending_id, approve_url, expires_at, reason }`: el gate de §6.1 deja el documento esperando aprobación humana cuando la organización está en producción y el monto supera su umbral (o pidió revisar todo). Ese documento no quema folio ni llega al SII hasta que una persona lo aprueba en `approve_url`; consulta en qué terminó con `GET /dtes/pendientes/{id}`. Por API key el gate no corre. Requiere el header `Idempotency-Key`. `X-Cert-Id` es opcional: con un solo certificado activo el servidor lo resuelve; con varios responde 400 `cert_id_ambiguous` y hay que indicar cuál firma (los lista `GET /certificates`). tipo_dte 52 (Guía de Despacho), 56 y 61 usan sus schemas dedicados: el 52 con el bloque `despacho` (Dte52EmitInput), el 56/61 con references obligatorias. tipo_dte 110 y 112 (exportación de servicios) también: llevan `tpo_moneda` con la GLOSA del catálogo del SII (`\"DOLAR USA\"`, nunca el código ISO `\"USD\"`), `ind_servicio` (3, 4 o 5 para prestación de servicios), todas las líneas exentas, y el bloque `aduana` con los puertos y `cod_pais_destin`. Los montos van EN LA MONEDA del documento y admiten 4 decimales. El receptor extranjero no necesita `rut`: el servidor pone el comodín `55555555-5` que el SII define para eso, y su identificación real va en `receptor.extranjero.num_id`. **El tipo de cambio lo resuelve el servidor** (fuente del día, cacheada): el `tpo_cambio` que venga en el body se guarda como evidencia y NUNCA convierte: si la fuente no responde, la emisión se detiene sin quemar folio en vez de asumir un valor. Emitir 110/112 exige que la organización tenga el tipo autorizado; si no, la respuesta es 403. tipo_dte 46 (Factura de Compra) usa este mismo schema (DteEmitInput) y su retención total de IVA la computa el SERVIDOR: a partir de la suma de los ítems afectos calcula neto, IVA = round(neto × 0,19) y la retención código 15, y emite `<ImptoReten>` en los Totales más `<CodImpAdic>15</CodImpAdic>` en cada línea del Detalle. Por eso `monto_neto`, `iva` y `monto_total` **se ignoran** cuando tipo_dte es 46: mándalo sólo con `items`. Ojo con el total: en una factura de compra `monto_total` es el NETO (el IVA lo retiene el comprador), no neto + IVA. El 46 es una operación 100% afecta: un ítem exento responde 422 `dte.46.invalid_afecta`, y tampoco admite `descuento_global`. El ambiente NO lo elige el cuerpo: sale de la API key (`api_keys.sii_env`). Mandar `sii_env` es opcional y vale como confirmación; si contradice el ambiente de la credencial, la respuesta es 422 `dte.sii_env_credential_mismatch` y no se emite nada. Para probar en certificación, usa una API key de certificación. `rut_emisor` se resuelve server-side desde la organización de la API key, no es necesario enviarlo. Para factura 33/34 y 46, receptor.giro / receptor.direccion / receptor.comuna y forma_pago (1=Contado, 2=Crédito, 3=Sin costo) son obligatorios (validación condicional por tipo; no expresada en el schema JSON required).","parameters":[{"schema":{"type":"string","description":"Obligatorio. UUIDv7 que generas TÚ, uno por documento. Reintentar con la MISMA clave devuelve el documento que ya se emitió, en vez de emitir otro; una clave distinta emite un documento nuevo."},"required":true,"name":"Idempotency-Key","in":"header"},{"schema":{"type":"string","format":"uuid","description":"Certificado digital con el que se firma. Opcional: con un solo certificado activo el servidor lo resuelve solo. Con varios, la respuesta es 400 `cert_id_ambiguous` y hay que mandar el UUID del que corresponda (`GET /certificates` los lista)."},"required":false,"name":"X-Cert-Id","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DteEmitInput"},{"$ref":"#/components/schemas/Dte52EmitInput"},{"$ref":"#/components/schemas/Dte56EmitInput"},{"$ref":"#/components/schemas/Dte61EmitInput"},{"$ref":"#/components/schemas/Dte110EmitInput"}]}}}},"responses":{"202":{"description":"DTE encolado: folio asignado, estado avanza async (poll links.self)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteEmitAccepted"}}}},"400":{"description":"Idempotency-Key faltante, JSON inválido, `cert_id_ambiguous` (varios certificados activos: manda X-Cert-Id), `cert_id_missing` (la empresa no tiene certificado) o validation_failed (con issues[])","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Cuota del plan free agotada (billing.free_tier_exceeded)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflicto de negocio (p.ej. NC sobre factura cedida sin override_cedida)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Regla SII violada (CAF agotado, plazo NC 6 meses, interés moratorio en ND, etc.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listDtes","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"Listar DTEs","description":"Paginación KEYSET: recorre pasando el `next_cursor` de la respuesta anterior en `?cursor=`, sin cambiar `sort`/`dir` (un cursor emitido con otro orden se rechaza con 422 en vez de saltar filas en silencio). `next_cursor: null` = última página.\n\nPara ubicar un documento que ya conoces sin recorrer el histórico, filtra por `folio` (y `tipo_dte` para la coordenada exacta) o por `rut_receptor`: el `id` que devuelve es el que piden `GET /dtes/{id}`, `/dtes/{id}/pdf-url` y `/dtes/{id}/xml`.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Default 20, máx 100"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"`next_cursor` de la página anterior. Opaco: no lo construyas ni lo modifiques."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","enum":["folio","monto_total","fecha_emision","sii_status","created_at"]},"required":false,"name":"sort","in":"query"},{"schema":{"type":"string","enum":["asc","desc"]},"required":false,"name":"dir","in":"query"},{"schema":{"type":"string","description":"Estados SII a incluir, separados por coma (p. ej. `queued,sending,SOK`). Un valor fuera del vocabulario devuelve 422.\n\nClasificación GENERADA del mismo catálogo que usa el runtime, no una lista escrita a mano que pueda contradecirlo:\n\n`terminal: true` (el SII ya dio su veredicto; volver a consultar no puede devolver otra cosa) → EPR, RPR, aceptado_con_reparos, accepted, RFR, RCT, RSC, RCH\n\n`terminal: false` (el estado todavía puede cambiar) → queued, sending, signed, awaiting_sii, SOK, CRT, FOK, PDR, PRD, -11, stuck, sin_permiso_sii\n\n`stuck` y `sin_permiso_sii` NO son terminales aunque ya no haya un poll detrás: el SII nunca llegó a juzgar el documento, así que `POST /dtes/{id}/refresh-status` vuelve a consultar y responde 202, no `already_terminal` (en `sin_permiso_sii`, después de enrolar el RUT del certificado en Mi SII → Usuarios autorizados). `accepted` son los documentos importados del Respaldo del SII: el Servicio ya los aceptó en su momento y no tienen envío que consultar. `signed` es el DTE ya firmado y todavía sin subir.\n\n`awaiting_sii` y `aceptado_con_reparos` están DEPRECADOS: ningún proceso de Notta los escribe hoy. Este filtro los sigue aceptando para no romper a quien ya los consultaba; en código nuevo usa `RPR`.\n\nLa glosa y la acción sugerida de cada estado viajan en el bloque `estado` de cada documento."},"required":false,"name":"sii_status","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":9999,"description":"Código SII del tipo de documento (33 factura, 34 exenta, 52 guía de despacho, 56 nota de débito, 61 nota de crédito). Un valor no numérico o fuera de rango devuelve 422 `dte.list.tipo_invalido`. Alcanza también los documentos importados del Respaldo del SII."},"required":false,"name":"tipo_dte","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":9999999999,"description":"Folio exacto. NO identifica un documento por sí solo: el mismo folio existe una vez por `tipo_dte` (y por ambiente), así que la respuesta es una lista, súmale `tipo_dte` para la coordenada exacta. Un valor no numérico o fuera de rango devuelve 422 `dte.list.folio_invalido`."},"required":false,"name":"folio","in":"query"},{"schema":{"type":"string","description":"RUT del receptor. Acepta puntos, espacios y la `k` en minúscula (se normaliza a `BODY-DV`). El dígito verificador NO se valida: la columna es lo que declaró el emisor, y un DV que no cierra igual corresponde a documentos reales. Una forma que no es un RUT devuelve 422 `dte.list.rut_receptor_invalido`."},"required":false,"name":"rut_receptor","in":"query"},{"schema":{"type":"string","description":"`fecha_emision >=` (YYYY-MM-DD, inclusive)"},"required":false,"name":"fecha_emision_desde","in":"query"},{"schema":{"type":"string","description":"`fecha_emision <=` (YYYY-MM-DD, inclusive)"},"required":false,"name":"fecha_emision_hasta","in":"query"},{"schema":{"type":"string","description":"Instante ISO-8601. Filtra por `sii_last_polled >=`, o sea TOCADO desde. Esa columna se estampa en cada escritura de estado, incluidas las de la emisión (`queued`, `sending`, `signed`), no solo en los polls al SII. Nunca pierde un cambio; sí devuelve documentos cuyo estado no cambió."},"required":false,"name":"polled_since","in":"query"},{"schema":{"type":"string","enum":["reclamado","aceptado","en_plazo","aceptado_tacito","sin_info"],"description":"Filtra por lo que hizo el receptor con el documento (no es `sii_status`). Acepta los mismos cinco valores que publica el campo `receptor_estado` de cada fila. `reclamado` y `aceptado` son HECHOS que el SII registró y no se mueven; `en_plazo`, `aceptado_tacito` y `sin_info` se calculan contra el instante del request, así que un documento puede cambiar de bucket entre la página 1 y la 2 de una misma consulta paginada. Si necesitas una foto estable, filtra en tu lado con `fecha_recepcion_sii` y `plazo_reclamo_cierra`, que vienen en cada fila. Un valor fuera de esos cinco devuelve 422 `dte.list.receptor_estado_invalido`."},"required":false,"name":"receptor_estado","in":"query"}],"responses":{"200":{"description":"Lista de DTEs del org (orden default: created_at desc)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteListResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Cursor inválido, estado SII desconocido, o `tipo_dte`/`folio`/`rut_receptor`/fecha/`polled_since`/`receptor_estado` mal formados","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}":{"get":{"operationId":"getDte","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"Detalle de un DTE","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"DTE con items por línea","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteDetail"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/totales":{"get":{"operationId":"getDteTotals","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"Totales agregados por período, tipo y estado, sin el detalle de cada documento","description":"Conteo y suma (neto/exento/IVA/total) agrupados por `tipo_dte` y `sii_status`, agregados en SQL. Nunca una fila por documento: no expone rut_receptor ni razon_social_receptor de ninguna contraparte. `periodo` es opcional (default: el mes actual, calendario chileno).","parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"YYYY-MM. Default: el mes actual (calendario chileno)"},"required":false,"name":"periodo","in":"query"}],"responses":{"200":{"description":"Totales del período por tipo y estado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteTotalsResponse"}}}},"400":{"description":"dte.totales.query_invalid: `periodo` no tiene formato YYYY-MM","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/pendientes/{id}":{"get":{"operationId":"getPendingAction","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"Estado de una solicitud que quedó esperando aprobación humana","description":"En qué terminó lo que el gate de §6.1 dejó pendiente: `pending` (nadie la ha visto todavía), `approved` (con `result_ref` apuntando al DTE emitido), `rejected` (con el motivo que escribió la persona, para corregir y reintentar) o `expired` (nadie la aprobó en 24 h; no consumió nada, se puede volver a pedir). Devuelve el ESTADO, nunca el pedido: ni el payload ni el monto.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Estado de la solicitud","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingActionState"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La credencial no tiene scope dte:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"pending_action_not_found: no existe en esta empresa, o su PII ya se ocultó por retención","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/pdf":{"get":{"tags":["dtes"],"summary":"Representación impresa (PDF con timbre PDF417)","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"PDF de la representación impresa (NF SII)","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"dte.pdf.not_signed: aún sin TED; poll links.xml y reintenta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/pdf-url":{"get":{"operationId":"getDtePdfUrl","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"URL firmada (15 min) para descargar el PDF sin sesión, para reenviar al cliente","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Enlace firmado de un solo documento, vence a los 15 minutos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DtePdfUrlResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/xml":{"get":{"tags":["dtes"],"summary":"XML firmado del DTE","description":"El `charset` de la respuesta lo dicta el prólogo del documento y los bytes SIEMPRE coinciden con él: un DTE emitido por Notta declara `encoding=\"ISO-8859-1\"` y baja con `charset=iso-8859-1` (byte-idéntico al que recibió el SII, para re-subirlo al portal o cederlo); uno importado del Respaldo SII no trae prólogo y baja en UTF-8. Decodifica según el `charset` del `Content-Type`, no asumas UTF-8.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"XML del DTE (firmado cuando está disponible; verifica la XML-DSig embebida)","content":{"application/xml":{"schema":{"type":"string"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"not_found, o dte.xml.not_yet_available si el workflow aún no firmó","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/events":{"get":{"operationId":"getDteEvents","security":[{"bearerAuth":["dte:read"]}],"tags":["dtes"],"summary":"Feed de cambios de estado del DTE","description":"Historia cronológica de transiciones de estado (queued → sending → EPR/RPR/RFR/RCT/RSC) con la glosa del SII. Es el camino de PULL: sirve para reconstruir por dónde pasó un documento, para reconciliar y para ponerte al día si una entrega de webhook no llegó. Si quieres enterarte en el momento sin pollear, registra un webhook con `POST /webhooks`.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Feed de transiciones de estado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteEventsFeed"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/refresh-status":{"post":{"operationId":"refreshDteStatus","security":[{"bearerAuth":["dte:write"]}],"tags":["dtes"],"summary":"Revivir el seguimiento de un DTE cuyo poll murió","description":"Vuelve a consultarle al SII el estado de un documento cuyo seguimiento automático ya no corre (`stuck`, `sin_permiso_sii`, o un reloj frío de más de 25 h). NO es el endpoint para enterarse de un cambio de estado: la emisión publica un poll durable que lleva el documento a su estado final por su cuenta, y para leer el resultado están `GET /dtes` (con `?polled_since=`) y `GET /dtes/{id}/events`. Llamarlo en bucle no acelera nada: cada llamada que SÍ encola arrastra su propia ventana de reintentos contra el SII con el certificado del cliente. Las tres respuestas traen el bloque `estado`: mira `estado.terminal` y `estado.accion` antes de volver a llamar.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"No se encoló nada, con el motivo: `already_terminal` (el SII ya dio su veredicto; viene con `sii_glosa`) o `poll_in_progress` (el poll durable sigue vivo; viene con `retry_after`). Reintentar no acelera nada.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteRefreshNotEnqueued"}}}},"202":{"description":"Poll de estado encolado: el estado se persiste async en el DTE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteRefreshAccepted"}}}},"400":{"description":"`cert_id_ambiguous` (la empresa tiene varios certificados activos: manda `X-Cert-Id`) o `cert_id_missing` (no tiene ninguno). Los produce el middleware compartido de /dtes en TODA mutación, antes de llegar al handler.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:write (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"dte.refresh_status.no_track_id (aún sin upload) o dte.refresh_status.no_cert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/{id}/anular":{"post":{"tags":["dtes"],"summary":"Anular una Guía de Despacho (52)","description":"Anula una Guía de Despacho electrónica registrando su campo `<Anulado>` en el Libro de Guías. SOLO aplica a Guías de Despacho (tipo 52): anular una guía NO es una Nota de Crédito. Para anular una FACTURA se emite una NC (61). Requiere scope `dte:write`. Es idempotente: reanular una guía ya anulada devuelve el mismo `anuladoEstado` sin volver a auditar. No se puede anular una guía ya facturada (una Factura la referencia) → 409 `guia.ya_facturada`.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuiaAnularInput"}}}},"responses":{"200":{"description":"Guía anulada: anuladoEstado 1 (pre-envío al SII) o 2 (post-envío)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteAnularResponse"}}}},"400":{"description":"motivo inválido / faltante (validation_failed con issues[]) o JSON inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"DTE inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"guia.tipo_invalido (el documento no es tipo 52) o guia.ya_facturada (una Factura la referencia)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/muestras":{"get":{"tags":["dtes"],"summary":"ZIP de Muestras Impresas (certificación SII)","description":"Arma un ZIP con un PDF por cada DTE firmado (33/34/56/61) del org para el lote de Muestras Impresas del SII. `?source=set_pruebas` lo acota al set de pruebas.","parameters":[{"schema":{"type":"string","enum":["set_pruebas"],"description":"Acota el lote a los DTE emitidos vía set de pruebas"},"required":false,"name":"source","in":"query"}],"responses":{"200":{"description":"ZIP con un PDF por DTE firmado","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"dte.muestras.empty: no hay DTE firmados (33/34/56/61) para el lote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/dtes/muestras/send":{"post":{"tags":["dtes"],"summary":"Enviar Muestras Impresas al SII por correo","description":"Notta arma y envía el correo de Muestras Impresas a `sii_dte_impresos@sii.cl` con un PDF por DTE firmado adjunto y el RUT del emisor en el asunto. Acción de salida: solo ocurre al confirmar.","parameters":[{"schema":{"type":"string","format":"uuid","description":"Opcional: con un solo certificado activo el middleware de /dtes lo resuelve. Con varios, 400 `cert_id_ambiguous` y hay que mandar el UUID del que corresponda."},"required":false,"name":"X-Cert-Id","in":"header"}],"responses":{"200":{"description":"Correo enviado: sentAt persistido en el avance de certificación","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DteMuestrasSendResponse"}}}},"400":{"description":"`cert_id_missing` (la empresa no tiene certificado) o `cert_id_ambiguous` (varios activos: manda X-Cert-Id)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"dte.muestras.no_samples, dte.muestras.too_large (>3MB) o dte.muestras.send_not_configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"dte.muestras.send_not_wired: envío no configurado en este entorno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/caf":{"post":{"tags":["caf"],"summary":"Subir archivo CAF (rango de folios del SII)","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CafUploadInput"}}}},"responses":{"201":{"description":"CAF registrado y cifrado; folios disponibles para emitir","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafUploadResponse"}}}},"400":{"description":"caf.invalid_request: falta el archivo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (rol viewer)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"caf.duplicate: el rango ya está registrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required: completa el onboarding primero","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"caf.parse_error, caf.wrong_tipo o caf.no_certificate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable o caf.kms_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listCaf","security":[{"bearerAuth":["dte:read"]}],"tags":["caf"],"summary":"Listar CAFs del org","responses":{"200":{"description":"CAFs con folios restantes y flag low_folios (≤10)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafListResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/caf/{id}":{"delete":{"tags":["caf"],"summary":"Eliminar un CAF","description":"Hard delete (permite re-subir el mismo rango). Bloqueado si algún DTE del CAF fue aceptado por el SII (folios comprometidos + retención legal de 6 años) o fue cedido vía RPETC.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"CAF eliminado (cascade de DTEs no aceptados)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafDeleteResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (rol owner/admin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"caf.not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"caf.has_accepted_dtes o caf.has_ceded_dtes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/caf/request":{"post":{"tags":["caf"],"summary":"Solicitar folios (timbraje on-demand)","description":"Solicita al SII un rango nuevo de folios (CAF) para un tipo. ⚠️ IRREVERSIBLE: el SII otorga folios reales que no se devuelven. Dual-auth: Bearer API key o sesión del dashboard; con Bearer el ambiente SII (cert/prod) sale de la API key. Requiere scope de escritura (un rol viewer recibe 403). Hay cooldown anti doble-grant.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafRequestInput"}}}},"responses":{"200":{"description":"Ya hay folios suficientes: no se pidió rango nuevo (reason=no_cafs_missing)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafRequestResponse"}}}},"201":{"description":"Rango de folios solicitado al SII (requested=true)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CafRequestResponse"}}}},"400":{"description":"caf.invalid_request: tipo faltante/no soportado o cantidad fuera de rango","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (rol viewer)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"caf.request_in_flight (cooldown, incluye retry_in_seconds) o caf.type_not_prod_certified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required (sesión sin org) o cert.missing (sin certificado activo)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"caf.request_failed o rechazo del SII","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable o caf.kms_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/certificates":{"post":{"tags":["certificates"],"summary":"Subir certificado digital (.p12)","description":"El .p12 se cifra con DEK per-org (envelope encryption). El id devuelto es el X-Cert-Id para emitir.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CertificateUploadInput"}}}},"responses":{"200":{"description":"Certificado actualizado en su lugar (mismo .p12 re-subido → re-deriva metadata / revive)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificateUploadResponse"}}}},"201":{"description":"Certificado almacenado cifrado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificateUploadResponse"}}}},"400":{"description":"cert.invalid_request: file, password y label son obligatorios","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (rol owner/admin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"cert.duplicate: mismo fingerprint ya subido para este org (race de upload concurrente); o situacion_tributaria.bloqueada: el SII confirmó que esta organización no puede emitir todavía (rut_inexistente o sin_inicio_actividades), gate/situacion-tributaria.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"cert.invalid: el .p12 o la clave no son válidos (no se pudo parsear el certificado)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable o cert.kms_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listCertificates","security":[{"bearerAuth":["certificates:read"]}],"tags":["certificates"],"summary":"Listar certificados del org","description":"Certificados vigentes (no eliminados) de la organización.","responses":{"200":{"description":"Certificados con vigencia (not_before / not_after)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificateListResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/certificates/{id}":{"delete":{"tags":["certificates"],"summary":"Eliminar un certificado","description":"Soft delete: deja de aparecer en el listado y de servir para firmar. No se puede borrar el ÚNICO certificado de la organización: para rotar tu firma, sube la nueva primero y recién entonces elimina la anterior.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Certificado eliminado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertificateDeleteResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (rol owner/admin)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"cert.not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"cert.last_remaining: es el único certificado de la organización","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/profile":{"get":{"operationId":"getProfile","security":[{"bearerAuth":["empresas:read"]}],"tags":["profile"],"summary":"Leer el perfil del emisor","description":"Giro / dirección / comuna / actividad económica que aparecen en el <Emisor> del DTE. `{}` si el org todavía no configuró ningún campo.","responses":{"200":{"description":"Perfil actual (campos ausentes si nunca se configuraron)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["profile"],"summary":"Actualizar el perfil del emisor","description":"Update parcial: solo los campos presentes en el body se mergean, el resto se preserva. `POST /dtes` con perfil incompleto devuelve `422 emisor.profile_incompleto` con el hint de completarlo acá.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"giro":{"type":"string","minLength":1,"maxLength":80},"direccion":{"type":"string","minLength":1,"maxLength":70},"comuna":{"type":"string","minLength":1,"maxLength":20},"actividadEconomica":{"type":"integer","minimum":0,"exclusiveMinimum":true}}}}}},"responses":{"200":{"description":"Perfil actualizado (forma completa post-merge)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"profile.invalid: campo vacío, fuera de ISO-8859-1, o actividadEconomica no entera","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/cert-state":{"get":{"operationId":"getSiiCertState","security":[{"bearerAuth":["empresas:read"]}],"tags":["sii"],"summary":"Estado del journey de certificación SII","description":"Journey derivado del último snapshot scrapeado del portal SII. `scrapedAt` es null si nunca se scrapeó.","responses":{"200":{"description":"Journey de certificación + timestamp del último scrape","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiiCertStateResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/readiness":{"get":{"operationId":"getSiiReadiness","security":[{"bearerAuth":["empresas:read"]}],"tags":["sii"],"summary":"Readiness de certificación SII del emisor","description":"Resumen de aplicabilidad/estado de certificación (ok, paso de postulación, fase, sub-estados por tipo).","responses":{"200":{"description":"Readiness de certificación de la org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiiReadinessResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/documents/recent":{"get":{"operationId":"listSiiRecentDocuments","security":[{"bearerAuth":["empresas:read"]}],"tags":["sii"],"summary":"Documentos de venta recientes (33/34)","description":"Últimas ventas 33/34 (máx 50) para pre-llenar el form desde el historial. Env-scopeado por el `sii_env` de la API key.","responses":{"200":{"description":"Lista de documentos recientes de la org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiiRecentDocumentsResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/documents/{id}/template":{"get":{"operationId":"getSiiDocumentTemplate","security":[{"bearerAuth":["empresas:read"]}],"tags":["sii"],"summary":"Template de un documento previo (para reusar en un nuevo DTE)","description":"Tipo + receptor + items de un documento previo. `?source=notta` (default) usa el DTE de Notta (env-scopeado); `?source=rcv` usa una venta del RCV del SII (pre-fill degradado, sin líneas).","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["notta","rcv"],"description":"Fuente del documento (default: notta)."},"required":false,"name":"source","in":"query"}],"responses":{"200":{"description":"Template para hidratar el form de un nuevo DTE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiiDocumentTemplateResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"document.not_found: inexistente, de otra org, o de otro env","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"document.not_templatable: solo 33/34 se pueden reusar como template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"db.unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/empresas":{"get":{"operationId":"listEmpresas","security":[{"bearerAuth":["empresas:read"]}],"tags":["empresas"],"summary":"Listar el catálogo de contrapartes (env activo)","responses":{"200":{"description":"Empresas del org, orden last_used_at desc","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"nullable":true}}},"required":["data"]}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope empresas:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["empresas"],"summary":"Crear una empresa manualmente","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rut":{"type":"string","description":"RUT canónico BODY-DV (solo en POST)","example":"78410502-4"},"razon_social":{"type":"string","maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20},"correos":{"type":"array","items":{"type":"string","format":"email"},"maxItems":5},"is_cliente":{"type":"boolean"},"is_proveedor":{"type":"boolean"}},"required":["rut","razon_social","is_cliente","is_proveedor"]}}}},"responses":{"200":{"description":"Empresa creada","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"nullable":true}}}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope empresas:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Ya existe una empresa viva con ese RUT (empresa.conflict)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Body inválido (validation_failed con issues[])","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/sii/empresas/{id}":{"get":{"operationId":"getEmpresa","security":[{"bearerAuth":["empresas:read"]}],"tags":["empresas"],"summary":"Detalle de una empresa","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Ficha completa","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"nullable":true}}}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope empresas:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Empresa inexistente (o de otra org/env)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["empresas"],"summary":"Editar una empresa (RUT inmutable)","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"razon_social":{"type":"string","maxLength":100},"giro":{"type":"string","maxLength":40},"direccion":{"type":"string","maxLength":70},"comuna":{"type":"string","maxLength":20},"correos":{"type":"array","items":{"type":"string","format":"email"},"maxItems":5},"is_cliente":{"type":"boolean"},"is_proveedor":{"type":"boolean"}},"required":["razon_social","is_cliente","is_proveedor"]}}}},"responses":{"200":{"description":"Empresa actualizada","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"nullable":true}}}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope empresas:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Empresa inexistente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Body inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["empresas"],"summary":"Borrar (soft-delete) una empresa","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Empresa borrada","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"nullable":true}}}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope empresas:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Empresa inexistente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/set-pruebas/status":{"get":{"tags":["set-pruebas"],"summary":"Estado de un run de Set de Pruebas","description":"Estado (aggregate + casos) del run identificado por `run_id`. El query param es obligatorio.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"run_id","in":"query"}],"responses":{"200":{"description":"Estado del run (aggregate_state + casos)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPruebasEnvelope"}}}},"400":{"description":"set_pruebas.run_id_required: falta el query param run_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/set-pruebas/latest":{"get":{"tags":["set-pruebas"],"summary":"Último run de Set de Pruebas de la org","responses":{"200":{"description":"Último run (o null si nunca corrió)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPruebasEnvelope"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/set-pruebas/{runId}/report":{"get":{"tags":["set-pruebas"],"summary":"Reporte XML de un run de Set de Pruebas","description":"Descarga el XML del reporte final (attachment, charset ISO-8859-1) del run, solo disponible cuando el run llegó a state='passed'. Se renderiza + cachea en el primer request.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"runId","in":"path"}],"responses":{"200":{"description":"XML del reporte final del run (attachment, charset ISO-8859-1)","content":{"application/xml":{"schema":{"type":"string"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"set_pruebas.run_not_found: run inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"set_pruebas.run_not_passed: el run no está en estado 'passed'","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/set-pruebas/result/{caseId}":{"get":{"tags":["set-pruebas"],"summary":"Resultado de un caso de Set de Pruebas","parameters":[{"schema":{"type":"string"},"required":true,"name":"caseId","in":"path"}],"responses":{"200":{"description":"Resultado del caso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPruebasEnvelope"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked: request cross-origin bloqueado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"caso inexistente (o de otra org)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcof":{"post":{"tags":["rcof"],"summary":"Enviar ConsumoFolio manual de un día","description":"Envío manual de un día (mismo path que el cron `rcof-daily-send`). Requiere scope `rcof:write` (un scope `dte:write` sin `rcof:write` no alcanza). Reenvíos del mismo día incrementan `sec_envio`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofSendInput"}}}},"responses":{"202":{"description":"RCOF encolado: estado avanza async (poll GET /rcof/{id})","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofSendAccepted"}}}},"400":{"description":"invalid_json o rcof.fecha_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope rcof:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"rcof.no_active_cert: no hay certificado activo para el org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["rcof"],"summary":"Listar envíos RCOF del org","parameters":[{"schema":{"type":"string","description":"YYYY-MM-DD"},"required":false,"name":"desde","in":"query"},{"schema":{"type":"string","description":"YYYY-MM-DD"},"required":false,"name":"hasta","in":"query"}],"responses":{"200":{"description":"Envíos RCOF, acotados al ambiente SII de la API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofListResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:read (default de lectura del mount RCOF)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcof/resend":{"post":{"tags":["rcof"],"summary":"Reenviar el ConsumoFolio de un día (corrección)","description":"Mismo handler que POST /rcof: re-encola con un `sec_envio` nuevo (corrección del mismo día).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofSendInput"}}}},"responses":{"202":{"description":"RCOF re-encolado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofSendAccepted"}}}},"400":{"description":"invalid_json o rcof.fecha_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope rcof:write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"rcof.no_active_cert: no hay certificado activo para el org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcof/{id}":{"get":{"tags":["rcof"],"summary":"Detalle de un envío RCOF","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Envío RCOF con el resumen agregado por tipo de documento","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcofDetailResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:read (default de lectura del mount RCOF)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"rcof.not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcof/{id}/xml":{"get":{"tags":["rcof"],"summary":"XML firmado del ConsumoFolio","description":"Los bytes coinciden con el prólogo del documento: el ConsumoFolio declara `encoding=\"ISO-8859-1\"` y baja en bytes ISO-8859-1. Decodifica según el `charset` del `Content-Type`.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"XML firmado del ConsumoFolio_v10 (charset ISO-8859-1)","content":{"application/xml":{"schema":{"type":"string"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope dte:read (default de lectura del mount RCOF)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"rcof.not_found o rcof.xml_not_available (aún sin firmar)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcv":{"post":{"tags":["rcv"],"summary":"Sincronizar snapshot mensual de RCV","description":"Sincroniza (o devuelve cacheado, salvo `force`) el Registro de Compras y Ventas de un período. Requiere scope `rcv:read` (cubre POST y GET: RCV no emite ni consume folios).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcvSyncInput"}}}},"responses":{"200":{"description":"Snapshot sincronizado o servido desde cache (from_cache)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcvSyncAccepted"}}}},"401":{"description":"Bearer API key faltante o inválida, o rcv.unauthorized (certificado digital rechazado por el SII)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope rcv:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"rcv.input.invalid (body no matchea {rut, periodo, type?, force?}) o rcv.period.invalid (periodo en el futuro)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"rcv.sync.failed: el SII no respondió o falló el fetch; reintentar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listRcv","security":[{"bearerAuth":["rcv:read"]}],"tags":["rcv"],"summary":"Listar o consultar snapshots RCV","description":"Con `rut` devuelve el detalle de un snapshot; sin `rut` devuelve la lista del período.","parameters":[{"schema":{"type":"string","description":"YYYY-MM, requerido"},"required":true,"name":"periodo","in":"query"},{"schema":{"type":"string","description":"Si se pasa, devuelve el detalle (no la lista)"},"required":false,"name":"rut","in":"query"},{"schema":{"type":"string","enum":["received","issued","both"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["rut","period","type","record_count","synced_at"]},"required":false,"name":"sort","in":"query"},{"schema":{"type":"string","enum":["asc","desc"]},"required":false,"name":"dir","in":"query"}],"responses":{"200":{"description":"Detalle (con rut) o { data: [...] } (sin rut)","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RcvSnapshot"},{"$ref":"#/components/schemas/RcvListResponse"}]}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope rcv:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"rcv.not_found: con rut, ningún snapshot para ese período","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"rcv.query.invalid: falta ?periodo=YYYY-MM","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/rcv/documents":{"get":{"operationId":"listRcvDocuments","security":[{"bearerAuth":["rcv:read"]}],"tags":["rcv"],"summary":"Registro de Compra y Venta, documento por documento","description":"Una fila por documento del registro del SII, con el vocabulario de Notta. `GET /rcv` devuelve el snapshot crudo del SII (útil para auditar); esto es la lectura tipada.\n\nPaginación KEYSET sobre el id: pasa el `next_cursor` en `?cursor=`. El id es estable entre re-sincronizaciones, así que un sync nuestro a mitad de tu recorrido no te reordena lo ya visto. `total` es el tamaño del universo que matchea el filtro, no el de la página: te sirve para verificar que leíste todo.\n\nSiempre acotado al ambiente SII de tu API key: cert y prod nunca se mezclan.","parameters":[{"schema":{"type":"string","enum":["issued","received"],"description":"Requerido. `issued` = ventas, `received` = compras"},"required":true,"name":"type","in":"query"},{"schema":{"type":"string","description":"YYYY-MM. Omitirlo devuelve todos los períodos"},"required":false,"name":"periodo","in":"query"},{"schema":{"type":"string","enum":["registro","pendiente","no_incluir","reclamado","all"],"description":"Sección del registro. Default `registro` (lo ya asentado), que OCULTA las otras tres, usa `all` si necesitas el período completo según el SII."},"required":false,"name":"estado","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"description":"Default 100, máx 500"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","description":"`next_cursor` de la página anterior"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Página de documentos del registro","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RcvDocumentRow"}},"total":{"type":"integer","description":"Filas que matchean el filtro completo, no la página"},"next_cursor":{"type":"string","nullable":true,"format":"uuid"},"synced_at":{"type":"string","nullable":true,"description":"Última sincronización del registro que alimenta esta consulta. `null` = NUNCA se sincronizó. Míralo antes de interpretar `total: 0`: sin este campo, «este período no tuvo documentos» y «todavía no bajamos los datos» se ven igual, y para quien concilia son lo opuesto."},"resumen_no_detallado":{"type":"array","items":{"type":"object","properties":{"periodo":{"type":"string","description":"YYYY-MM"},"tipo_dte":{"type":"integer"},"documentos":{"type":"integer","description":"Cuántos documentos resume esta fila. NO es un folio."},"monto_neto":{"type":"integer"},"monto_exento":{"type":"integer"},"monto_iva":{"type":"integer"},"monto_total":{"type":"integer"}},"required":["periodo","tipo_dte","documentos","monto_neto","monto_exento","monto_iva","monto_total"]},"description":"**Plata que NO está en `data`.** Para once tipos de documento (boletas 35/38/39/41, vale 47, comprobante de pago 48, boleta liquidación 105 y los resúmenes 919/920/922/924) el SII no entrega el detalle: entrega un total del período. Esas filas no son documentos (no tienen folio, ni contraparte, ni fecha de emisión) y por eso no pueden estar en `data`.\n\n**Si vas a sumar, suma `data[].monto_total` MÁS `resumen_no_detallado[].monto_total`.** Sumar solo `data` da de menos, y no de poco: en una empresa medida en producción el 97% de sus ventas del período vivía aquí. Mismo filtro que `data` y `total` (tipo, período, estado).\n\nArreglo vacío = el período no tiene documentos de esos tipos, que es el caso normal. No hay forma de pedir el detalle: el SII no lo tiene."}},"required":["data","total","next_cursor","synced_at","resumen_no_detallado"]}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope rcv:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"rcv.query.invalid (falta `type`, `periodo`/`estado` inválidos) o rcv.cursor.invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/recepcion":{"get":{"operationId":"listRecepcion","security":[{"bearerAuth":["recepcion:read"]}],"tags":["recepcion"],"summary":"Listar la bandeja de compras (Casilla de Intercambio)","description":"Cola de documentos recibidos por la Casilla de Intercambio (dte@notta.cl) con el plazo de 8 días corridos para acusar o reclamar ya computado por fila (Ley 19.983). Acotada al ambiente SII de tu credencial (el `sii_env` de la API key; en el navegador, el ambiente activo de la sesión), igual que `/rcv`, no se puede elegir por query. Las compras que solo están en el Registro de Compras (`origen='rcv'`) aparecen únicamente en el ambiente de producción. Solo lectura: registrar un acuse o reclamo (`POST /recepcion/{id}/evento`) registra ante el SII por SOAP y notifica al emisor por correo. pedido por un agente entra siempre a la cola de aprobación (ver `registrarEventoRecepcion`).","parameters":[{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"description":"1-based, default 1, máx 100000"},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"description":"Default 100, máx 500"},"required":false,"name":"pageSize","in":"query"}],"responses":{"200":{"description":"Documentos de la cola + el total de filas que calzan el filtro (no el tamaño de esta página)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecepcionListResponse"}}}},"400":{"description":"recepcion.query_invalid: page/pageSize no son enteros válidos, o pageSize > 500","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene scope recepcion:read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/recepcion/{id}/evento":{"post":{"operationId":"registrarEventoRecepcion","security":[{"bearerAuth":["recepcion:write"]}],"tags":["recepcion"],"summary":"Acusar recibo o reclamar un documento de compra ante el SII","description":"Registra la acción en el Registro de Aceptación o Reclamos del SII (RAR, Ley 20.956) y le responde al proveedor por correo con los XML firmados. **Efecto irreversible y excluyente**: dado un acuse ya no se puede reclamar y viceversa, y aceptada la factura el proveedor puede cederla a factoring. Pedido por un agente (MCP) NO se ejecuta: entra SIEMPRE a la cola de aprobación y responde 202 con `approve_url`, sin umbral de monto y sin excepción por ambiente. Consulta el estado con `getPendingAction`. Requiere `Idempotency-Key`: reintentar con la misma clave devuelve el mismo pendiente, no crea otro.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","description":"UUID por pedido. Obligatorio para agentes: dedupea el reintento."},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecepcionEventoBody"}}}},"responses":{"202":{"description":"El pedido quedó esperando aprobación humana; NO se registró nada ante el SII","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecepcionEventoPendingResponse"}}}},"400":{"description":"recepcion.evento_invalid_input (acción no válida) o idempotency_key_missing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer faltante o inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Sin scope recepcion:write, o la empresa tiene la escritura por MCP apagada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"recepcion.rar_cedible_warning: el documento ya es cedible; requiere `cedidaOverride`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"recepcion.rar_evento_rechazado (codResp del SII) o recepcion.rar_tipo_no_soportado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Tope de acciones por minuto de las conexiones MCP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/onboarding/readiness":{"get":{"operationId":"getOnboardingReadiness","security":[{"bearerAuth":["empresas:read"]}],"tags":["onboarding"],"summary":"Checklist de qué le falta a la org para emitir","description":"Cert vigencia, CAF por tipo-objetivo, set de pruebas y producción. `complete=true` cuando todo pasa.","responses":{"200":{"description":"Readiness actual","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/onboarding/suggested-types":{"get":{"operationId":"getSuggestedDteTypes","security":[{"bearerAuth":["empresas:read"]}],"tags":["onboarding"],"summary":"Tipos DTE sugeridos según la postulación SII del certificado","description":"Catálogo completo con `preselected` marcado por lo que el scrape de postulación detectó. Factura afecta (33) siempre presente aunque el SII no la haya devuelto (el scrape es frágil).","responses":{"200":{"description":"Catálogo + tipos sugeridos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestedTypesResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/onboarding/target-types":{"post":{"tags":["onboarding"],"summary":"Confirmar los tipos DTE que la org va a emitir","description":"Persiste los tipos-objetivo. Si la org estaba en fase cert_uploaded, la avanza a sandbox_ready (habilita el orquestador de certificación).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tipos":{"type":"array","items":{"anyOf":[{"type":"number","enum":[33]},{"type":"number","enum":[34]},{"type":"number","enum":[39]},{"type":"number","enum":[41]},{"type":"number","enum":[46]},{"type":"number","enum":[52]},{"type":"number","enum":[56]},{"type":"number","enum":[61]}]},"minItems":1,"maxItems":10},"autopilot":{"type":"boolean"},"mailContacto":{"type":"string","maxLength":50,"format":"email","description":"Correo del Usuario-Administrador que se declara al SII (MAIL_SUP del formulario de postulación). Sólo se persiste cuando `autopilot` es true: sin ese consentimiento no hay inscripción que hacer y el campo se ignora."}},"required":["tipos"]}}}},"responses":{"200":{"description":"Tipos-objetivo persistidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TargetTypesResponse"}}}},"400":{"description":"bad_request: tipos requerido, array de números","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked, o la API key no tiene scope de escritura (dte:write)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"situacion_tributaria.bloqueada: el SII confirmó que esta organización todavía no puede emitir (`estado`: rut_inexistente o sin_inicio_actividades). No se resuelve reintentando: hay que arreglarlo en el SII y revalidar.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"412":{"description":"org.required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/billing/plan":{"get":{"operationId":"getBillingPlan","security":[{"bearerAuth":["billing:read"]}],"tags":["billing"],"summary":"Estado de cuota del plan actual","description":"Plan activo (`free` si no hay suscripción) + documentos usados / límite del mes en curso (prod). Chequealo antes de emitir para evitar el 402 `billing.free_tier_exceeded` de POST /dtes.","responses":{"200":{"description":"Estado de cuota","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanStatus"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no tiene el scope 'billing:read'","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/billing/subscribe":{"post":{"operationId":"subscribeBilling","tags":["billing"],"summary":"Suscribirse a un plan","description":"Activa (o reemplaza) la suscripción de la org al `planId` indicado. Planes pagos requieren `card_token` + `payment_method_id` (tokenizados client-side vía MercadoPago Card Payment Brick).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSubscribeInput"}}}},"responses":{"200":{"description":"Suscripción activa","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSubscribeResult"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"billing.payment_rejected: MercadoPago rechazó el primer cobro","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"csrf_blocked (carril sesión), o la API key no tiene el scope 'billing:write'","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"billing.already_subscribed: cancela el plan actual antes de cambiarte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"billing.plan_not_found | billing.card_required | validación de body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"billing.mercadopago_auth: token de MercadoPago inválido (no reintentable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"billing.mercadopago_unavailable | billing.config_missing | billing.upgrade_failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks":{"post":{"operationId":"createWebhook","security":[{"bearerAuth":["webhook:write"]}],"tags":["webhooks"],"summary":"Registrar un webhook de cambios de estado de DTE","description":"Registra una URL https a la que Notta hace POST cada vez que cambia el estado SII de un documento. La suscripción vale para UN ambiente: el de la API key que la crea, no un campo del cuerpo. Una key de certificación nunca recibe documentos de producción. El `secret` viene en esta respuesta y en ninguna otra. Header `Idempotency-Key` obligatorio: repetir la misma key devuelve la misma suscripción con 200 en vez de crear otra. Cada entrega viaja firmada en el header `Notta-Signature` (`t=<unix>,v1=<hmac-sha256 hex>` sobre `${t}.${cuerpo crudo}`, tolerancia de 5 minutos). Las entregas pueden llegar desordenadas y repetidas: ordena por `data.observed_at` y haz tu handler idempotente por el `id` del evento. Una emisión exitosa produce cuatro entregas (`queued` no avisa; sí `sending`, el intermedio del SII y el veredicto): si sólo te interesa el desenlace, suscríbete a `dte.accepted` y `dte.rejected`. Cuál sea el estado intermedio varía (`-11`, `SOK`, `CRT`, `FOK`, `PDR`, `PRD`), así que ramifica por `data.terminal` y `data.categoria`, nunca por el string de `data.sii_status`. Una suscripción de solo desenlace tiene un punto ciego: un documento que termina en `requiere_accion` (`stuck`, `sin_permiso_sii`) viaja como `dte.status_changed` y nunca como `dte.accepted` ni `dte.rejected`, así que esos quedan sin aviso. Tu endpoint tiene 10 segundos para responder 2xx: pasado ese plazo el intento cuenta como fallido.","parameters":[{"schema":{"type":"string","description":"Obligatorio. UUIDv7 que generas TÚ, uno por documento. Reintentar con la MISMA clave devuelve el documento que ya se emitió, en vez de emitir otro; una clave distinta emite un documento nuevo."},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookInput"}}}},"responses":{"200":{"description":"Replay de una `Idempotency-Key` ya usada: la misma suscripción, sin crear otra.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"201":{"description":"Suscripción creada. El `secret` sólo aparece aquí.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"400":{"description":"`idempotency_key_missing` (falta el header) o `invalid_json`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no porta el scope `webhook:write` (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"`validation_failed` (la `url` o los `events` no cumplen el schema) o `invalid_webhook_url` (la URL no es https pública: localhost, rango privado, metadata o puerto propio)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"operationId":"listWebhooks","security":[{"bearerAuth":["webhook:read"]}],"tags":["webhooks"],"summary":"Listar los webhooks registrados","description":"Las suscripciones de la organización en el ambiente de la API key, sin el secret (no es recuperable). Una key de certificación no lista las suscripciones de producción, ni al revés. Si una trae `active: false`, mira `disabled_reason`: la apagamos porque tu servidor dejó de responder y no estás recibiendo eventos. `webhook:write` NO incluye `webhook:read`: son dos llaves, no una jerarquía.","responses":{"200":{"description":"Suscripciones de la organización en el ambiente de la key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no porta el scope `webhook:read` (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","security":[{"bearerAuth":["webhook:write"]}],"tags":["webhooks"],"summary":"Borrar una suscripción de webhook","description":"Deja de entregar eventos a ese endpoint y borra TODO su registro de entregas, entregadas incluidas. No es reversible: registrar la misma URL después crea otra suscripción con otro secret. Un id de otro ambiente devuelve 404 aunque sea de tu misma organización.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Suscripción borrada. Sin cuerpo."},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no porta el scope `webhook:write` (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`not_found`: no existe, es de otra organización o es de otro ambiente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","security":[{"bearerAuth":["webhook:write"]}],"tags":["webhooks"],"summary":"Rotar el signing secret de una suscripción","description":"Genera un secret nuevo y lo devuelve una sola vez. El anterior deja de firmar de inmediato: toda entrega posterior a esta llamada viaja firmada con el nuevo, así que despliega el valor en tu verificador antes de rotar o vas a rechazar entregas legítimas.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Secret rotado. El valor nuevo sólo aparece aquí.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no porta el scope `webhook:write` (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`not_found`: no existe, es de otra organización o es de otro ambiente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/test":{"post":{"operationId":"testWebhook","security":[{"bearerAuth":["webhook:write"]}],"tags":["webhooks"],"summary":"Enviar una entrega de prueba","description":"Encola una entrega de prueba contra la URL registrada para que verifiques firma y conectividad. Viaja SIEMPRE con `type: \"dte.status_changed\"` y `data.sii_status: \"TEST\"`, aunque el endpoint no esté suscrito a ese evento: prueba el transporte, no el ruteo. Si tu handler ramifica por `type`, contempla ese caso o vas a descartar tu propia prueba. El `dte_id` es el UUID nulo y el `folio` es 0: no hay documento detrás. Si la suscripción está apagada (`active: false`) responde 409 y NO encola nada: una suscripción apagada no se reactiva, hay que borrarla y registrarla de nuevo, y el alta nueva trae otro secret.","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"202":{"description":"Entrega de prueba encolada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestAccepted"}}}},"401":{"description":"Bearer API key faltante o inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"La API key no porta el scope `webhook:write` (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`not_found`: no existe, es de otra organización o es de otro ambiente","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`webhook_endpoint_disabled`: la suscripción está apagada y no entrega nada, así que la prueba no se encoló. El motivo viaja en `detail.disabled_reason`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}