# Empresas (/docs/referencia/empresas)

Base: `https://api.facturia.cl/v1`. Todos los endpoints de este capítulo se autentican con `Authorization: Bearer` salvo que se diga lo contrario, y el sobre de error es el de [Errores](/docs/errores).

El orden de este capítulo es el orden en que conviene recorrerlo, y empieza por el **mandato**: es el paso 1 de los dos carriles de la puesta en marcha, y el certificado (o la credencial del portal) es el 2. Subir el certificado antes funciona, pero el paso queda `pending` hasta que la máquina llegue a `certificate_pending`. El camino completo está en [De sandbox a producción](/docs/empezar/produccion).

| Método   | Ruta                                                                                                                                                                | Qué hace                                                                                                        |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `GET`    | [`/empresas`](#get-empresas)                                                                                                                                        | Lista las empresas que esta llave puede ver                                                                     |
| `POST`   | [`/empresas`](#post-empresas)                                                                                                                                       | Crea una empresa                                                                                                |
| `GET`    | [`/empresas/{empresa_id}`](#get-empresas-empresa-id)                                                                                                                | Devuelve una empresa                                                                                            |
| `PATCH`  | [`/empresas/{empresa_id}`](#patch-empresas-empresa-id)                                                                                                              | Actualiza una empresa                                                                                           |
| `DELETE` | [`/empresas/{empresa_id}`](#delete-empresas-empresa-id)                                                                                                             | Borra una empresa de SANDBOX                                                                                    |
| `GET`    | [`/empresas/{empresa_id}/mandato`](#get-empresas-empresa-id-mandato)                                                                                                | Si el representante legal firmó, contra qué términos, y cómo                                                    |
| `POST`   | [`/empresas/{empresa_id}/mandato`](#post-empresas-empresa-id-mandato)                                                                                               | Registra el mandato que autoriza a Facturia a actuar ante el SII                                                |
| `DELETE` | [`/empresas/{empresa_id}/mandato`](#delete-empresas-empresa-id-mandato)                                                                                             | Revoca el mandato                                                                                               |
| `GET`    | [`/empresas/{empresa_id}/certificate`](#get-empresas-empresa-id-certificate)                                                                                        | Devuelve los metadatos del certificado                                                                          |
| `POST`   | [`/empresas/{empresa_id}/certificate`](#post-empresas-empresa-id-certificate)                                                                                       | Carga (o reutiliza) el certificado digital de la empresa                                                        |
| `DELETE` | [`/empresas/{empresa_id}/certificate`](#delete-empresas-empresa-id-certificate)                                                                                     | Purga el certificado de la bóveda (revoca la custodia y suspende la emisión)                                    |
| `GET`    | [`/empresas/{empresa_id}/sfg_credential`](#get-empresas-empresa-id-sfg-credential)                                                                                  | Consulta los metadatos de custodia de la clave centralizada del SFG                                             |
| `POST`   | [`/empresas/{empresa_id}/sfg_credential`](#post-empresas-empresa-id-sfg-credential)                                                                                 | Guarda (o reemplaza) la clave centralizada del SFG                                                              |
| `DELETE` | [`/empresas/{empresa_id}/sfg_credential`](#delete-empresas-empresa-id-sfg-credential)                                                                               | Destruye la clave centralizada del SFG (termina la custodia)                                                    |
| `POST`   | [`/empresas/{empresa_id}/mandato/revocation_link`](#post-empresas-empresa-id-mandato-revocation-link)                                                               | Acuña la página alojada donde el representante legal revoca                                                     |
| `POST`   | [`/empresas/{empresa_id}/resolucion/verify`](#post-empresas-empresa-id-resolucion-verify)                                                                           | Verifica una resolución declarada con un único timbraje de producción (solo operadores de Facturia)             |
| `GET`    | [`/empresas/{empresa_id}/counterparties`](#get-empresas-empresa-id-counterparties)                                                                                  | Las contrapartes a las que has facturado, con la dirección y los contactos que tienes registrados para cada una |
| `GET`    | [`/contribuyentes/{rut}`](#get-contribuyentes-rut)                                                                                                                  | Lo que el SII publica sobre una empresa, por RUT, y un giro que cabe en la factura                              |
| `GET`    | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}`](#get-empresas-empresa-id-counterparties-counterparty-rut)                                              | Lo que sabes de una contraparte, y si lo declaraste tú o lo inferimos nosotros                                  |
| `PATCH`  | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}`](#patch-empresas-empresa-id-counterparties-counterparty-rut)                                            | Deja registrados la razón social, el giro y la dirección de una contraparte                                     |
| `GET`    | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts`](#get-empresas-empresa-id-counterparties-counterparty-rut-contacts)                            | Los contactos registrados para una contraparte                                                                  |
| `POST`   | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts`](#post-empresas-empresa-id-counterparties-counterparty-rut-contacts)                           | Registrar un contacto responsable                                                                               |
| `PATCH`  | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts/{contact_id}`](#patch-empresas-empresa-id-counterparties-counterparty-rut-contacts-contact-id)  | Edit a contact, promote it, or record an opt-out                                                                |
| `DELETE` | [`/empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts/{contact_id}`](#delete-empresas-empresa-id-counterparties-counterparty-rut-contacts-contact-id) | Sacar un contacto de la agenda                                                                                  |
| `GET`    | [`/empresas/{empresa_id}/onboarding`](#get-empresas-empresa-id-onboarding)                                                                                          | Ciclo de vida de la puesta en marcha, sus pasos y las acciones humanas que la bloquean                          |
| `POST`   | [`/empresas/{empresa_id}/onboarding/links`](#post-empresas-empresa-id-onboarding-links)                                                                             | Acuna un enlace a una pagina alojada para el representante legal                                                |
| `DELETE` | [`/empresas/{empresa_id}/onboarding/links/{step}`](#delete-empresas-empresa-id-onboarding-links-step)                                                               | Revoca un enlace alojado del representante legal                                                                |
| `POST`   | [`/empresas/{empresa_id}/onboarding/go_live`](#post-empresas-empresa-id-onboarding-go-live)                                                                         | Pide al titular que apruebe la puesta en marcha, o declara la decisión en su nombre                             |
| `POST`   | [`/empresas/{empresa_id}/onboarding/steps/{step}/recheck`](#post-empresas-empresa-id-onboarding-steps-step-recheck)                                                 | Avísanos que una persona hizo su paso, y vamos a mirar                                                          |
| `POST`   | [`/empresas/{empresa_id}/onboarding/steps/{step}/attest`](#post-empresas-empresa-id-onboarding-steps-step-attest)                                                   | Registra que una persona realizó un paso que este build no puede comprobar por sí solo (#395)                   |
| `POST`   | [`/empresas/{empresa_id}/onboarding/steps/{step}/approve`](#post-empresas-empresa-id-onboarding-steps-step-approve)                                                 | Registrar la autorización del titular para un paso que después ejecutamos nosotros (#452, #453)                 |
| `GET`    | [`/empresas/{empresa_id}/onboarding/certification`](#get-empresas-empresa-id-onboarding-certification)                                                              | El set de pruebas: qué se cargó, qué falta y qué contestó el SII                                                |
| `POST`   | [`/empresas/{empresa_id}/onboarding/certification/set_file`](#post-empresas-empresa-id-onboarding-certification-set-file)                                           | Sube el set de pruebas que el SII emitió para esta empresa                                                      |
| `POST`   | [`/empresas/{empresa_id}/onboarding/certification/inputs`](#post-empresas-empresa-id-onboarding-certification-inputs)                                               | Entrega los datos que el set de pruebas no trae                                                                 |
| `GET`    | [`/empresas/{empresa_id}/onboarding/evidence`](#get-empresas-empresa-id-onboarding-evidence)                                                                        | La rendicion de cuentas: lo que hicimos por la empresa ante el SII                                              |
| `GET`    | [`/empresas/{empresa_id}/onboarding/evidence/export`](#get-empresas-empresa-id-onboarding-evidence-export)                                                          | La rendicion de cuentas como un solo archivo CSV                                                                |
| `GET`    | [`/empresas/{empresa_id}/automation_settings`](#get-empresas-empresa-id-automation-settings)                                                                        | Devuelve las automatizaciones de la empresa                                                                     |
| `PATCH`  | [`/empresas/{empresa_id}/automation_settings`](#patch-empresas-empresa-id-automation-settings)                                                                      | Actualiza las automatizaciones de la empresa                                                                    |
| `GET`    | [`/empresas/{empresa_id}/branding`](#get-empresas-empresa-id-branding)                                                                                              | Lee el logo, el formato de impresión por defecto y el texto del pie                                             |
| `PATCH`  | [`/empresas/{empresa_id}/branding`](#patch-empresas-empresa-id-branding)                                                                                            | Actualiza el logo, el formato de impresión por defecto y el pie de página                                       |

## `GET /empresas` [#get-empresas]

**Lista las empresas que esta llave puede ver**

Lista todas las empresas que esta llave puede alcanzar — su propia lista blanca resuelta a filas reales, o toda la cuenta si la llave no tiene restricción.

```bash
curl -sS https://api.facturia.cl/v1/empresas \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro | En    | Requerido | Tipo                                               | Notas                                                            |
| --------- | ----- | --------- | -------------------------------------------------- | ---------------------------------------------------------------- |
| `limit`   | query | —         | integer                                            |                                                                  |
| `cursor`  | query | —         | string                                             | Cursor opaco tomado del `next_cursor` de una respuesta anterior. |
| `status`  | query | —         | `onboarding` · `active` · `suspended` · `archived` |                                                                  |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                                                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `200`     | Una lista de empresas.                                                                                                                                                                                                                                                                                                    | lista de [Empresa](/docs/referencia/esquemas#empresa) |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                                         |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                                         |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                                         |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                                         |

## `POST /empresas` [#post-empresas]

**Crea una empresa**

En modo test la empresa nace `emitting`: sin mandato, sin certificado, sin certificación. En modo
live parte en `mandato_pending` y avanza por la máquina de estados de la puesta en marcha.

**`origen` ES OBLIGATORIO EN MODO LIVE** y esta operación rechaza sin él — `400 invalid_field` con
`param: "origen"` (#495). No está en `required` arriba porque el modo es una propiedad de la
CREDENCIAL, no del cuerpo, y un esquema no puede decir «obligatorio cuando el bearer empieza con
`sk_live_`»: declararlo sin condición haría que toda llamada de sandbox — donde el campo defaultea
a `ninguno` — fallara la validación del propio cliente generado antes de salir de la máquina. Así
que la regla vive en el `400` de abajo, donde un cliente generado al menos la ve, y en la
descripción del campo.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"rut":"77928532-4","legal_name":"Connect SpA"}'
```

**Parámetros**

| Parámetro         | En     | Requerido | Tipo   | Notas                                                                                                                                                                                                                                     |
| ----------------- | ------ | --------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Idempotency-Key` | header | —         | string | Llave que genera el cliente, única por operación lógica, retenida 24 h y con alcance (cuenta, empresa, endpoint). Un replay devuelve la respuesta original con `Facturia-Idempotent-Replay: true`. Misma llave y cuerpo distinto → `409`. |

**Cuerpo**

| Campo                | Tipo                                                     | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------- | -------------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rut`                | Rut                                                      | sí        | RUT canónico: sin puntos, un guion y K mayúscula. Ej.: `"77928532-4"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `legal_name`         | string                                                   | sí        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `giro`               | string                                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `acteco`             | integer\[]                                               | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `address`            | Address                                                  | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `codigo_sucursal`    | integer,null                                             | —         | Código de sucursal del SII (`CdgSIISucur`). Omítelo, o envía null, para casa matriz.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `contact_email`      | string                                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `emission_channel`   | `mercado` · `sfg`                                        | —         | Cómo va a emitir esta empresa. `mercado` corre el motor certificado de Facturia y la certificación de once pasos; `sfg` opera el Sistema de Facturación Gratuito del SII para una empresa que ya está inscrita ahí, y sigue un checklist corto sin certificación. Elegir `sfg` para una empresa que NO está inscrita no la inscribe: el paso `emisor_verificado` lo va a decir. Elegir `mercado` para una que está cómoda en el portal gratuito inicia una certificación que no necesita. `ambiente` se DERIVA de este campo y no se acepta acá — ver `Empresa.ambiente`. Por defecto: `"mercado"`.                                                                                                                                                                                                                                                                                                                                          |
| `doc_types`          | `33` · `34` · `39` · `41` · `46` · `52` · `56` · `61`\[] | —         | QUÉ VA A EMITIR ESTA EMPRESA — la declaración que mueve la certificación y qué folios se piden; `capabilities.tipos` es lo que puede emitir AHORA. Por defecto `[33, 34, 61]`; un `[]` explícito es `400 invalid_field`, porque una empresa con cero tipos no puede terminar nunca la certificación. Declarar 39 o 41 (boletas) con `emission_channel: sfg` es `422 doc_type_not_supported_on_channel`: el Portal MIPYME gratuito del SII no expone formulario de boleta. Las boletas necesitan el canal `mercado`, donde además agregan el paso `habilitacion` al checklist. Por defecto: `[33,34,61]`.                                                                                                                                                                                                                                                                                                                                     |
| `origen`             | `gratuito` · `mercado` · `ninguno`                       | —         | **OBLIGATORIO EN MODO LIVE** — una llave `sk_live_` que lo omita recibe `400 invalid_field` con `param: "origen"`, que es la primera empresa de todo cliente real. No está en la lista `required` de este esquema porque el modo es una propiedad de la credencial y no del cuerpo; el `400` de la operación declara el rechazo (#495). Opcional en modo test, donde defaultea a `ninguno` porque una empresa de sandbox nace emitiendo y nunca ve el asistente que este campo enruta. Mira el esquema `Origen` para qué decide y qué no.                                                                                                                                                                                                                                                                                                                                                                                                    |
| `resolucion`         | ResolucionClaimRequest                                   | —         | **LA RESOLUCIÓN QUE ESTA EMPRESA YA TIENE** (fallo 2026-09-07). Mándala cuando la empresa ya factura electrónicamente con otro proveedor; manda `null` para borrarla. Las dos mitades están impresas en la carátula de todo documento tributario electrónico que la empresa emite hoy (`NroResol`, `FchResol`), así que un agente las lee de una factura reciente en vez de mandar a alguien al SII. &#x2A;*ES UNA DECLARACIÓN, NO UN ATAJO.** Escribe dos columnas y no mueve nada más: la empresa se sigue creando en `mandato_pending`, sigue necesitando el certificado y el mandato, y sigue certificándose salvo que nuestro propio timbraje de producción pruebe la resolución. Ese timbraje se hace sólo cuando un operador de Facturia lo confirma para esta empresa; mientras tanto la declaración se lee `resolucion.verification_status: pending_verification`. El resultado se lee en `resolucion.verified` del objeto empresa. |
| `resolucion_boletas` | ResolucionBoletasClaimRequest                            | —         | **LA HABILITACIÓN DE BOLETAS QUE ESTA EMPRESA YA TIENE** (fallo 2026-09-07). Mándala junto a un `doc_types` que traiga 39 o 41; manda `null` para borrarla. No lleva `numero` porque el SII no emite ninguno para boletas: la habilitación llega como «habilitados los documentos de boleta electrónica a contar del …», y esa fecha es todo. Se verifica con un timbraje de producción de tipo 39 o 41, igual que la resolución; si el SII lo rechaza, aparecen en la lista los pasos de habilitación normales.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Respuestas**       |                                                          |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

| Código    | Significado                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Cuerpo                                       |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `201`     | La empresa creada.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | [Empresa](/docs/referencia/esquemas#empresa) |
| `400`     | Entrada mal formada. Los códigos que responde esta operación:   \* `invalid_rut` — falta `rut`, o su dígito verificador está mal.   \* `invalid_field` con `param: "legal_name"` — ausente o vacío.   \* `invalid_field` con `param: "origen"` — &#x2A;*ausente, con una llave live.** La primera empresa de     todo cliente real cae acá si el llamador trató el campo como opcional porque el esquema lo es.     Ver la descripción de la operación.   \* `invalid_field` con `param: "doc_types"` — no es un arreglo de tipos soportados, o es un `[]`     explícito.   \* `invalid_field` con `param: "emission_channel"` / `"acteco"` / `"codigo_sucursal"` — un valor     fuera de lo que el campo admite.   \* `invalid_field` con `param: "ambiente"` — `ambiente` es derivado y se rechaza en vez de     ignorarse. | ErrorResponse                                |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | ErrorResponse                                |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | ErrorResponse                                |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | ErrorResponse                                |
| `422`     | `doc_type_not_supported_on_channel` — `doc_types` nombra un tipo que el `emission_channel` resultante no puede construir (39/41 en `sfg`). `error.param` es `doc_types`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | ErrorResponse                                |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | ErrorResponse                                |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | ErrorResponse                                |

## `GET /empresas/{empresa_id}` [#get-empresas-empresa-id]

**Devuelve una empresa**

Una empresa: identidad legal, `ambiente`, `emission_channel`/`certification_track`, el estado de puesta en marcha y `capabilities`.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                                       |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `200`     | La empresa.                                                                                                                                                                                                                                                                                                               | [Empresa](/docs/referencia/esquemas#empresa) |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                                |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                                |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse                                |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                                |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                                |

## `PATCH /empresas/{empresa_id}` [#patch-empresas-empresa-id]

**Actualiza una empresa**

Actualiza `legal_name`, `giro`, `contact_email`, `acteco` u `origen`. `ambiente` es derivado y se rechaza si lo envías (`422`); `origen` es la declaración del titular sobre cómo emite la empresa hoy, corregible, nunca una preferencia de canal.

EL ESPEJO DEL PANEL ES MÁS ANGOSTO. `PATCH /dashboard/empresas/\{empresa_id\}` — el mismo handler
detrás de una sesión de cuenta — acepta solo `doc_types` y `certification_track`, y rechaza
cualquier otro campo con `400 invalid_field` nombrándolo. Esos dos son los que el asistente de
puesta en marcha tiene que anotar; el resto es la identidad tributaria con la que se imprime cada
documento, y una sesión de navegador no es la credencial que reescribe lo que el SII ve en una
factura. Una llave `sk_` en ESTA ruta no se ve afectada.

```bash
curl -sS -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"legal_name":"Connect SpA","giro":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                 | Tipo                                                     | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| --------------------- | -------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `legal_name`          | string                                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `giro`                | string                                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `acteco`              | array,null                                               | —         | Códigos de actividad económica del SII, del más específico al menos; el primero se vuelve `&lt;Acteco&gt;` en el bloque emisor de cada documento. Un arreglo vacío — o null — lo limpia. Omitir el campo deja el valor guardado tal cual.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `address`             | Address                                                  | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `codigo_sucursal`     | integer,null                                             | —         | Código de sucursal del SII (`CdgSIISucur`); null lo limpia de vuelta a casa matriz. Omitir el campo deja el valor guardado tal cual — una distinción que aquí importa, porque la vista previa del Portal MIPYME de una empresa SFG rechaza un documento cuyo origen del emisor está incompleto.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `contact_email`       | string                                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `doc_types`           | `33` · `34` · `39` · `41` · `46` · `52` · `56` · `61`\[] | —         | QUÉ VA A EMITIR ESTA EMPRESA — la declaración que mueve la certificación y qué folios se piden. Para lo que puede emitir AHORA, lee `capabilities.tipos`. Un arreglo vacío es `400 invalid_field`: una empresa con cero tipos no puede terminar nunca la certificación. Omitir el campo deja el valor guardado como está. AGREGAR un tipo a una empresa que ya está `emitting` reabre su checklist en `certification_in_progress` — la certificación y el CAF son por tipo, y el SII solo autoriza los tipos que certificaste. Agregar 39 o 41 es lo que hace aparecer el paso `habilitacion`, EN CUALQUIERA DE LOS DOS CANALES. LAS BOLETAS SÍ SE PUEDEN EN EL CANAL `sfg`, y declarar una es precisamente cómo se pide la habilitación. El Portal MIPYME gratuito del SII no expone formulario de boleta para nadie, así que una 39/41 sale siempre por nuestro propio motor, emita la empresa por donde emita — o sea que una empresa puede seguir emitiendo sus facturas por el portal gratuito y que nosotros le corramos la certificación de boletas por detrás. Los pasos `habilitacion` y `folios` aparecen en el checklist del carril gratuito apenas declaras una boleta, y `capabilities.tipos` suma 39/41 cuando el SII las habilita. EL TIPO 46 EN EL CANAL `sfg` ES `422 doc_type_not_supported_on_channel`: a diferencia de una boleta, no es un documento que nuestro motor arme en ese carril, así que necesita `emission_channel: "mercado"`. El mismo rechazo salta cuando se mueve `emission_channel` a `sfg` con un 46 ya declarado. |
| `certification_track` | `mercado` · `sfg` · `null`                               | —         | QUÉ CHECKLIST RIGE A ESTA EMPRESA — seteable desde #474, porque el código siempre lo leyó y ninguna superficie podía declararlo: `PATCH \{emission_channel: "sfg"\}` movía los tipos, el ambiente y el driver y dejaba a la empresa en el checklist de mercado de diez pasos con `blocked_on: mandato`, una lista que un emisor SFG nunca camina. `null` significa «no persigue la certificación» y es una respuesta real y permanente. Ponerlo en `null` o en `sfg` ESCONDE el checklist de mercado SIN borrar nada: los registros de los pasos quedan exactamente como están, y devolver el track a `mercado` los muestra de nuevo, sin cambios. Es una proyección, no una escritura destructiva.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `origen`              | `gratuito` · `mercado` · `ninguno`                       | —         | Corregible, y la única forma de que una empresa creada antes de que el campo existiera llegue a tener uno.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `emission_channel`    | `mercado` · `sfg`                                        | —         | Corregible, como `origen`: una empresa puede entrar al carril SFG o salir de él. Moverla a `sfg` pone `ambiente` en `produccion` en la misma escritura, porque una empresa en el sistema gratuito es emisora de producción. Moverla a `mercado` deja `ambiente` intacto — la resolución es lo único que lo mueve en el otro sentido. NO cambia `certification_track` por sí solo — ese es un campo aparte de este mismo cuerpo de petición (#474). Son dos hechos y cada uno se declara donde corresponde.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `resolucion`          | ResolucionClaimRequest                                   | —         | **LA RESOLUCIÓN QUE ESTA EMPRESA YA TIENE** (fallo 2026-09-07). Mándala cuando la empresa ya factura electrónicamente con otro proveedor; manda `null` para borrarla. Las dos mitades están impresas en la carátula de todo documento tributario electrónico que la empresa emite hoy (`NroResol`, `FchResol`), así que un agente las lee de una factura reciente en vez de mandar a alguien al SII. &#x2A;*ES UNA DECLARACIÓN, NO UN ATAJO.** Escribe dos columnas y no mueve nada más: la empresa se sigue creando en `mandato_pending`, sigue necesitando el certificado y el mandato, y sigue certificándose salvo que nuestro propio timbraje de producción pruebe la resolución. Ese timbraje se hace sólo cuando un operador de Facturia lo confirma para esta empresa; mientras tanto la declaración se lee `resolucion.verification_status: pending_verification`. El resultado se lee en `resolucion.verified` del objeto empresa.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `resolucion_boletas`  | ResolucionBoletasClaimRequest                            | —         | **LA HABILITACIÓN DE BOLETAS QUE ESTA EMPRESA YA TIENE** (fallo 2026-09-07). Mándala junto a un `doc_types` que traiga 39 o 41; manda `null` para borrarla. No lleva `numero` porque el SII no emite ninguno para boletas: la habilitación llega como «habilitados los documentos de boleta electrónica a contar del …», y esa fecha es todo. Se verifica con un timbraje de producción de tipo 39 o 41, igual que la resolución; si el SII lo rechaza, aparecen en la lista los pasos de habilitación normales.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `status`              | `active` · `archived`                                    | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Respuestas**        |                                                          |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                                       |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `200`     | La empresa actualizada.                                                                                                                                                                                                                                                                                                   | [Empresa](/docs/referencia/esquemas#empresa) |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse                                |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                                |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                                |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse                                |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                                |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                                |

## `DELETE /empresas/{empresa_id}` [#delete-empresas-empresa-id]

**Borra una empresa de SANDBOX**

Bota una empresa de prueba. &#x2A;*Solo sandbox.**

Una empresa de sandbox no guarda nada que sea un registro tributario: sus documentos son
simulados, nunca llegó al SII, y no reserva nada — ni el RUT (la unicidad es por modo) ni la
casilla `<rut>@dte.facturia.cl`, que solo llevan las empresas live. Por eso se puede borrar, y
la empresa junto con todo lo que cuelga de ella se va en una sola transacción.

Una empresa LIVE es `409 empresa_delete_not_allowed`, siempre. §7.1: los documentos emitidos son
registros tributarios. Las dos salidas reales son `DELETE /v1/empresas/\{empresa_id\}/mandato`
(termina la autorización, cláusula 7.1.3) y `PATCH /v1/empresas/\{empresa_id\}` con
`\{"status": "archived"\}` (detiene emisión y cobro); las dos conservan el historial.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Deleted. No body.                                                                                                                                                                                                                                                                                                         | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `409`     | `empresa_delete_not_allowed` — la empresa es live. Revoca el mandato y/o archívala.                                                                                                                                                                                                                                       | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/mandato` [#get-empresas-empresa-id-mandato]

**Si el representante legal firmó, contra qué términos, y cómo**

La mitad de lectura del modo alojado. Acuña un `signing_url` con un `POST` vacío, envíaselo a
la representante legal, y luego consulta este endpoint — la finalización la puede observar el agente
que lo pidió, sin suscribirse a un webhook ni inferirla desde `steps[].status`.

Dos campos responden preguntas que el checklist de onboarding no puede. `terms_current: false` en un
mandato `signed` significa que el texto avanzó y el pipeline ya dejó de confiar en esa aceptación -
hay que hacer `POST` de nuevo para recolectar una nueva. Y `acceptance_method` distingue una
*aprobación* (`hosted`: una persona del rol requerido completó una página que le mostró lo que
estaba firmando) de una *atestación* (`api`: la afirmación de un integrador de que alguien firmó).
Son dos tipos de evidencia distintos.

`signing_url` es SIEMPRE `null` acá: solo se guarda un SHA-256 del token, así que ninguna lectura
puede reproducirlo. Un `POST` con cuerpo vacío vuelve a acuñarlo, revocando el enlace anterior.

`status: "none"` para una empresa a la que todavía no se le ha pedido nada. Es un estado, no un
recurso faltante - la empresa existe y estás autorizado para verla.

Scope: `mandato:write` (que `empresas:write` implica). El scope que acuña el enlace
es el mismo que lee si se usó.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/mandato \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | El mandato, o un estado `none` cuando todavía no se le ha pedido nada a nadie.                                                                                                                                                                                                                                            | Mandato       |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/mandato` [#post-empresas-empresa-id-mandato]

**Registra el mandato que autoriza a Facturia a actuar ante el SII**

Envía la aceptación que recolectaste tú mismo, u omite el cuerpo para recibir un
`signing_url` alojado que enviarle al representante legal.

Registramos que ocurrió una aceptación, quién la hizo, desde dónde, y contra qué bytes exactos
del texto del mandato. NO verificamos una firma electrónica avanzada: si se requiere una es una
pregunta legal abierta, y hasta que se responda este endpoint no afirma más de lo que la
evidencia que tiene.

Mientras `GET /v1/mandato_terms` reporte `status: "draft"`, una aceptación en modo real se
rechaza con `422 mandato_terms_draft` — la misma advertencia que imprime el §7.3, ahora aplicada.

**Dos formas, dos scopes (ADR-0012 §4).** Sin cuerpo — acuñar el enlace de firma
para el representante legal — necesita `mandato:write`, que `empresas:write` implica. Con
cuerpo — afirmando una firma que recolectaste en tu propio flujo — es una *atestación* y
necesita `mandato:attest` **por sí mismo**: `empresas:write` NO lo implica (corregido el
2026-09-03), así que una llave que antes enviaba un cuerpo bajo solo `empresas:write` ahora
recibe `403 insufficient_scope` nombrando `mandato:attest`.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/mandato \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requested_by":"…","representante_legal":{}}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                 | Tipo              | Requerido | Notas                                                                                                                                                                                                                       |
| --------------------- | ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `requested_by`        | RequestedBy + any | —         |                                                                                                                                                                                                                             |
| `representante_legal` | object            | —         |                                                                                                                                                                                                                             |
| `accepted_at`         | string            | —         | Cuándo aceptó el representante legal. Si viene en el futuro, se ajusta al momento actual.                                                                                                                                   |
| `accepted_ip`         | string            | —         |                                                                                                                                                                                                                             |
| `accepted_user_agent` | string            | —         |                                                                                                                                                                                                                             |
| `terms_version`       | string            | —         |                                                                                                                                                                                                                             |
| `evidence`            | object            | —         | Los mismos hechos con la forma que produce naturalmente una página de firma. Se acepta como alternativa a los campos planos de arriba y se conserva íntegro en la rendición de cuentas junto a lo que registramos nosotros. |
| **Respuestas**        |                   |           |                                                                                                                                                                                                                             |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `201`     | El mandato.                                                                                                                                                                                                                                                                                                               | Mandato       |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `DELETE /empresas/{empresa_id}/mandato` [#delete-empresas-empresa-id-mandato]

**Revoca el mandato**

Cláusula 7.1: en cualquier tiempo, sin expresión de causa, sin sanción y sin terminar el contrato. La empresa pasa a `suspended` de inmediato, todo lo que estuviera en cola se cancela en la misma transacción, y el paso `mandato` vuelve a `action_required`.

**Esto es una atestación, no una escritura (ADR-0012 §4, ticket #465).** Es el acto de mayor efecto del contrato, así que `empresas:write` NO alcanza: se manda con `mandato:attest`, que se concede explícitamente, nunca lo implica `empresas:write` y nunca está en el vocabulario del MCP. Una sesión del panel también puede llamarlo — una sesión es el titular de la cuenta en persona. Cualquier otra cosa recibe `403 insufficient_scope`, cuyo `error.details` trae `required_scope` y el `\{method, url\}` que acuña la página alojada de revocación para el representante legal (`POST /empresas/\{empresa_id\}/mandato/revocation_link`).

NO destruye el certificado — eso es `DELETE .../certificate`, una revocación aparte con su propio plazo. Y no deshace lo anterior: la posición de la empresa queda registrada, así que una nueva aceptación la devuelve donde estaba en vez de reiniciar la puesta en marcha.

La empresa SIGUE SIENDO LEGIBLE mientras está suspendida (ticket #515): `GET /empresas/\{id\}`, `GET .../onboarding` y `GET .../mandato` responden, `onboarding.blocked_on` nombra `mandato`, y `onboarding.pending_action` es el handoff `mandato_revocado` cuyo `link.mint` vuelve a firmar. `active` no se toca — un derecho que el contrato llama reversible no se implementa nunca como una desaparición.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/mandato \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Revocado. La empresa pasa a `suspended`, y sigue siendo legible.                                                                                                                                                                                                                                                          | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/certificate` [#get-empresas-empresa-id-certificate]

**Devuelve los metadatos del certificado**

Solo metadatos. Ni el .pfx ni su contraseña se pueden leer nunca por la API.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/certificate \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | Metadatos del certificado.                                                                                                                                                                                                                                                                                                | Certificate   |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/certificate` [#post-empresas-empresa-id-certificate]

**Carga (o reutiliza) el certificado digital de la empresa**

Carga el `.pfx` de la empresa (`multipart/form-data` con `file` y `password`) o reutiliza el certificado válido de otra empresa (`reuse_from_empresa`). Un certificado vencido se rechaza al momento de cargarlo.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/certificate \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -F "file=…" \
  -F "password=…"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo (multipart/form-data)**

| Campo                | Tipo   | Requerido | Notas                                                                                                                                                                               |
| -------------------- | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `file`               | string | —         | Archivo PKCS#12 (.pfx).                                                                                                                                                             |
| `password`           | string | —         | La contraseña del .pfx.                                                                                                                                                             |
| `reuse_from_empresa` | string | —         | En vez de cargarlo, referencia un certificado que ya tienes en otra empresa de esta cuenta. Vale solo si ese certificado es usuario autorizado ante el SII del RUT de esta empresa. |
| **Respuestas**       |        |           |                                                                                                                                                                                     |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `201`     | Certificado guardado y verificado.                                                                                                                                                                                                                                                                                        | Certificate + object |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse        |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse        |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse        |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse        |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse        |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse        |

## `DELETE /empresas/{empresa_id}/certificate` [#delete-empresas-empresa-id-certificate]

**Purga el certificado de la bóveda (revoca la custodia y suspende la emisión)**

Elimina los metadatos del certificado guardado. La empresa vuelve a necesitar uno antes de poder firmar algo que el SII acepte.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/certificate \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Purgado.                                                                                                                                                                                                                                                                                                                  | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/sfg_credential` [#get-empresas-empresa-id-sfg-credential]

**Consulta los metadatos de custodia de la clave centralizada del SFG**

Solo metadatos: si tenemos la clave guardada y desde cuándo. El valor en sí nunca es
legible a través de la API: no existe ningún camino de código en este endpoint que lo
desencripte.

Solo una empresa `emission_channel: sfg` en modo real la tiene. Una empresa mercado firma
con el certificado en custodia y nunca le pide al SII que firme por ella, y una empresa en
modo de prueba no tiene Portal MIPYME en absoluto; ambas responden `422` señalando la
corrección.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/sfg_credential \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | El registro de custodia.                                                                                                                                                                                                                                                                                                  | SfgCredential |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/sfg_credential` [#post-empresas-empresa-id-sfg-credential]

**Guarda (o reemplaza) la clave centralizada del SFG**

El valor va directo a la bóveda de cada tenant y su id a la fila de credenciales de la
empresa; no existe una columna en texto plano. Reemplazarlo destruye primero el secreto
saliente, así que la destrucción queda en el registro de custodia y no como un efecto
colateral que nadie puede señalar.

La respuesta son los mismos metadatos que devuelve `GET`. La clave no se repite de vuelta.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/sfg_credential \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"clave_centralizado":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                | Tipo   | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------- | ------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clave_centralizado` | string | sí        | La clave del certificado CENTRALIZADO de la empresa en el SII. UN SOLO NOMBRE DE CAMPO, SIN SINÓNIMOS: `clave`, `password` y `clave_tributaria` se rechazan con `400 invalid_field` en vez de aceptarse igual. El único error que este endpoint existe para hacer imposible es que un cliente nos entregue la clave de su portal del SII bajo un nombre de campo con el que fuimos poco estrictos. |
| **Respuestas**       |        |           |                                                                                                                                                                                                                                                                                                                                                                                                    |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `201`     | Stored.                                                                                                                                                                                                                                                                                                                   | SfgCredential + object |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse          |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse          |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse          |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse          |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse          |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse          |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse          |

## `DELETE /empresas/{empresa_id}/sfg_credential` [#delete-empresas-empresa-id-sfg-credential]

**Destruye la clave centralizada del SFG (termina la custodia)**

Destruye los bytes. `204` incluso cuando no había nada que destruir — pediste un estado
(«no guardas nada mío»), y ese estado es el resultado de cualquiera de las dos formas.

A diferencia de `DELETE .../certificate`, esto NO retrocede el onboarding de la empresa:
la próxima emisión SFG se rechaza por falta de una clave con la que firmar, algo que la
ruta de emisión ya reporta con honestidad, y una clave se puede volver a entregar en una
sola llamada.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/sfg_credential \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Destroyed.                                                                                                                                                                                                                                                                                                                | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/mandato/revocation_link` [#post-empresas-empresa-id-mandato-revocation-link]

**Acuña la página alojada donde el representante legal revoca**

La cláusula 7.1 es de quien firmó, y así se le pone delante (ticket #465). La aceptación ya le entrega esta dirección una vez, y el correo-recibo la lleva; este endpoint es para todos los momentos posteriores — el correo se perdió, nunca salió, o el cliente le está pidiendo ayuda a su integrador para parar.

Tener el enlace no es tener el poder: la página exige el RUT del representante legal **tal como quedó registrado en el mandato que firmó**, que esta respuesta deliberadamente no repite. Acuñar revoca cualquier enlace de revocación anterior, que es lo que significa «de un solo uso» cuando un enlace se reemite.

La URL se devuelve UNA SOLA VEZ — de ese token solo se guarda su SHA-256. No vence: el derecho al que apunta tampoco.

`409 mandato_not_signed` cuando no hay nada vigente, porque una dirección para un derecho que no se puede ejercer es peor que un rechazo que lo dice.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/mandato/revocation_link \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `201`     | El enlace. Se devuelve una sola vez.                                                                                                                                                                                                                                                                                      | MandatoRevocationLink |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse         |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse         |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse         |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse         |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse         |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse         |

## `POST /empresas/{empresa_id}/resolucion/verify` [#post-empresas-empresa-id-resolucion-verify]

**Verifica una resolución declarada con un único timbraje de producción (solo operadores de Facturia)**

**SÓLO PARA OPERADORES — NINGUNA LLAVE DE API LA PUEDE LLAMAR** (sii-api#581 D1, decisión
del fundador del 2026-09-23). Está documentada para que un integrador sepa qué mueve
`resolucion.verification_status` y quién lo mueve.

Una resolución declarada en `POST`/`PATCH /v1/empresas` es una declaración. Se verifica
pidiéndole al SII de PRODUCCIÓN UN rango de folios de un tipo de factura declarado: el SII no
timbra para un RUT que no autorizó para ese tipo, así que un rango otorgado es la prueba. Esa
petición es irreversible (un rango registrado se usa o se anula), así que se hace sólo cuando
un operador de Facturia la confirma para esta empresa. Nada se pide de forma implícita, nada
durante `POST /v1/empresas` y nada contra el ambiente de certificación.

Sin `confirm: true` la llamada se rechaza con `400 confirmation_required` y nombra la petición
exacta en el mensaje y en `error.details.request`. Con él, se registra la confirmación (quién,
cuándo, por qué) y se encola UN trabajo `folio_request`; la respuesta del SII mueve después
`resolucion.verification_status` de `pending_verification` a `verified` o `refused`. Un intento
que no obtiene respuesta sobre el RUT (el bloqueo del borde del SII, un certificado inutilizable)
queda en `pending_verification`.

`409 resolucion_verification_not_allowed` nombra el hecho que bloquea en
`error.details.reason`: `sandbox`, `sfg_channel`, `no_claim`, `already_verified`,
`refused`, `in_flight`, `range_registered`, `not_ready` (la empresa no está en
`certificate_verified`) o `no_factura_tipo`.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/resolucion/verify \
  -H "X-Admin-Secret: $FACTURIA_OPERATOR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"confirm":true,"authorized_by":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo           | Tipo        | Requerido | Notas                                                                                   |
| --------------- | ----------- | --------- | --------------------------------------------------------------------------------------- |
| `confirm`       | boolean     | sí        | Debe ser `true`. Cualquier otra cosa es `400 confirmation_required` y no se envía nada. |
| `authorized_by` | string      | sí        | La persona que confirma. Queda registrada junto a la respuesta del SII.                 |
| `reason`        | string,null | —         | Why, in a sentence (the ticket, the customer). Recorded.                                |
| **Respuestas**  |             |           |                                                                                         |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `202`     | Confirmado. La única petición de producción queda encolada; la respuesta del SII llega a `resolucion`.                                                                                                                                                                                                                    | ResolucionVerification |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse          |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse          |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse          |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse          |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse          |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse          |

## `GET /empresas/{empresa_id}/counterparties` [#get-empresas-empresa-id-counterparties]

**Las contrapartes a las que has facturado, con la dirección y los contactos que tienes registrados para cada una**

Una lista DERIVADA, no almacenada: lee los receptores de los documentos que esta empresa ya emitió (tipos 33, 34, 56 y 61) y le une los contactos y las entradas de la libreta de direcciones que existan, así la pantalla abre como una lista para completar y no en blanco. También aparece una contraparte que tenga dirección o contacto pero todavía ningún documento.

Los campos de dirección salen solo de la libreta de direcciones. Cuando no hay ninguna registrada quedan en null, y `source` también, que en esta lista significa «no hay nada registrado» y no «no se sabe nada» — la lectura de una sola contraparte es la que recurre a lo que dijeron los documentos anteriores.

`has_more` es siempre `false`. La ventana acota el ESCANEO, no una página de resultados, y prometer un cursor que esta forma no puede honrar sería peor que decirlo.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `200`     | Las contrapartes, de la más reciente a la más antigua.                                                                                                                                                                                                                                                                    | lista de Counterparty |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse         |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse         |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse         |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse         |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse         |

## `GET /contribuyentes/{rut}` [#get-contribuyentes-rut]

**Lo que el SII publica sobre una empresa, por RUT, y un giro que cabe en la factura**

La razón social y las actividades económicas que el SII publica para una persona jurídica, y un
`giro` sugerido que cabe en el receptor de una factura (hasta 40 caracteres, ISO-8859-1).
Sirve para prellenar a un cliente antes de la primera factura.

La fuente es la nómina pública de personas jurídicas del SII
([https://www.sii.cl/sobre\_el\_sii/nominapersonasjuridicas.html](https://www.sii.cl/sobre_el_sii/nominapersonasjuridicas.html)), que el SII vuelve a publicar
cada algunos meses y que no garantiza completa ni al día. `source.published_at` dice qué
edición respondió. Las personas naturales no están en ella: su RUT responde 404, igual que un
RUT que no existe.

Una SUGERENCIA, no una afirmación: nada de esto se escribe solo en un documento. Muéstraselo a
la persona y, una vez confirmado, regístralo con
`PATCH /v1/empresas/\{id\}/counterparties/\{rut\}`: eso es lo que lee la próxima emisión.

`suggested_giro.basis` es `curated` cuando el texto viene de la redacción corta de Facturia
para un código de actividad común (las descripciones oficiales suelen pasar de 40 caracteres, y
una cortada cambiaría lo que dice la factura), y `sii_description` cuando la descripción oficial
cabe tal cual. Null cuando no aplica ninguna: pregúntale a la persona.

No depende de una empresa: los datos son públicos y de un tercero, así que no hace falta
`Facturia-Empresa`. Límite de 120 consultas por minuto por cuenta.

```bash
curl -sS https://api.facturia.cl/v1/contribuyentes/{rut} \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro | En   | Requerido | Tipo | Notas                                                                                  |
| --------- | ---- | --------- | ---- | -------------------------------------------------------------------------------------- |
| `rut`     | path | sí        | Rut  | El RUT de cualquier persona jurídica, canónico (`76000002-7`), con puntos o sin guion. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | The contribuyente.                                                                                                                                                                                                                                                                                                        | Contribuyente |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `404`     | La nómina no tiene este RUT (una persona natural, o una empresa que no existe).                                                                                                                                                                                                                                           | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `503`     | La nómina todavía no se ha cargado (`contribuyentes_unavailable`). Reintenta después de `Retry-After`.                                                                                                                                                                                                                    | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/counterparties/{counterparty_rut}` [#get-empresas-empresa-id-counterparties-counterparty-rut]

**Lo que sabes de una contraparte, y si lo declaraste tú o lo inferimos nosotros**

La entrada de tu libreta de direcciones para este RUT: la razón social, el giro y el domicilio que pondremos en el próximo documento dirigido a él.

Dos fuentes, en el mismo orden en que las usa la resolución de emisión. Si dejaste una dirección registrada, esa es la respuesta y `source` es `api`. Si no la dejaste, pero ya emitiste un documento a este RUT, la respuesta se lee del más reciente y `source` lo dice — eso es inferencia y no una declaración, y es la diferencia que conviene conocer antes de gastar un folio. Si no existe ninguna de las dos, esto es un 404.

La contraparte no tiene id: hay exactamente una identidad por RUT, así que el RUT es la clave.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut} \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `200`     | The counterparty.                                                                                                                                                                                                                                                                                                         | CounterpartyIdentity |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse        |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse        |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse        |
| `404`     | No hay nada registrado para este RUT y nunca se le emitió un documento.                                                                                                                                                                                                                                                   | ErrorResponse        |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse        |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse        |

## `PATCH /empresas/{empresa_id}/counterparties/{counterparty_rut}` [#patch-empresas-empresa-id-counterparties-counterparty-rut]

**Deja registrados la razón social, el giro y la dirección de una contraparte**

El SII no acepta una factura cuyo receptor no tenga giro, dirección y comuna: acepta el SOBRE y después rechaza el DOCUMENTO, y el folio se gasta igual. Registrar la dirección aquí responde eso una vez y no en cada emisión — y es la única fuente que puede responder por una contraparte que nunca facturaste, que es justo cuando la pregunta duele.

Es un upsert: la primera llamada crea la entrada y las siguientes la editan. No hay POST ni DELETE, porque la entrada no tiene ciclo de vida propio.

Parcial. Un campo que no envías conserva su valor; un campo enviado como `null` se borra. Cada valor se somete al mismo límite del esquema del SII al que se somete un valor enviado en un documento — `giro` 40 caracteres, `address.street` 70, `address.comuna` y `address.city` 20, `legal_name` 100 — y a la misma regla ISO-8859-1. Pasado el límite se rechaza, nunca se trunca: acortar un giro en silencio cambiaría lo que cada documento a esa contraparte dice sobre quién es.

No hace falta ningún documento previo. Registrar la dirección de un RUT que todavía no facturaste es precisamente el punto.

```bash
curl -sS -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut} \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"legal_name":"Connect SpA","giro":"…"}'
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |

**Cuerpo**

| Campo          | Tipo                | Requerido | Notas                                                                                                                                                                                                                                                                      |
| -------------- | ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `legal_name`   | string,null         | —         | RznSocRecep, at most 100 characters.                                                                                                                                                                                                                                       |
| `giro`         | string,null         | —         | GiroRecep, 40 caracteres como máximo — la mitad de lo que se permite en el giro del propio emisor, y el tope que más veces muerde. Se rechaza pasado el límite, nunca se trunca.                                                                                           |
| `address`      | CounterpartyAddress | —         | El domicilio del receptor, con los elementos del propio SII: street es DirRecep, comuna es CmnaRecep, city es CiudadRecep. Siempre presente como objeto, aunque todas sus partes sean null, para que un cliente nunca tenga que proteger el padre antes de leer una parte. |
| **Respuestas** |                     |           |                                                                                                                                                                                                                                                                            |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `200`     | La contraparte registrada.                                                                                                                                                                                                                                                                                                | CounterpartyIdentity |
| `400`     | Un RUT mal formado, un cuerpo que no nombra ningún campo, un valor más largo que el elemento del SII en que se convierte (`field_too_long`) o uno que lleva un carácter que ISO-8859-1 no puede representar (`unencodable_character`).                                                                                    | ErrorResponse        |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse        |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse        |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse        |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse        |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse        |

## `GET /empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts` [#get-empresas-empresa-id-counterparties-counterparty-rut-contacts]

**Los contactos registrados para una contraparte**

El contacto principal viene primero: es el único al que se notifica.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut}/contacts \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                       |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `200`     | The contacts.                                                                                                                                                                                                                                                                                                             | lista de CounterpartyContact |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse                |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                |

## `POST /empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts` [#post-empresas-empresa-id-counterparties-counterparty-rut-contacts]

**Registrar un contacto responsable**

Un contacto sin atestación es un estado legítimo: queda guardado, se muestra, y nunca se le escribe. Mandar `opt_in: true` sin `opt_in_method` se rechaza, porque un consentimiento registrado sin registrar cómo se obtuvo no es un registro.

El primer contacto de una contraparte queda como principal salvo que digas lo contrario.

Un número que se dio de baja no se puede volver a agregar con otro id: eso es `422 contact_opted_out`, y es lo que impide que borrar y volver a crear deshaga un STOP.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut}/contacts \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"cliente — Comercial Andina","phone":"+56912345678"}'
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |

**Cuerpo**

| Campo                | Tipo                                                              | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| -------------------- | ----------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | string                                                            | sí        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `phone`              | string                                                            | sí        | E.164. Cualquier cosa que no se pueda llevar a esa forma es `400 invalid_phone`. Ej.: `"+56912345678"`.                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `counterparty_name`  | string,null                                                       | —         | Reemplaza la razón social que traían los documentos, sólo para mostrar.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `primary`            | boolean                                                           | —         | Por defecto `true` para el primer contacto de una contraparte, `false` después.                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `opt_in`             | boolean                                                           | —         | Tu atestación de que esta persona aceptó recibir notificaciones por WhatsApp de tu parte. Omitirlo es un estado legítimo: el contacto queda guardado como agenda y nunca se le escribe (motivo de omisión `no_optin`).                                                                                                                                                                                                                                                                                                    |
| `opt_in_method`      | `en_persona` · `telefono` · `email` · `escrito` · `otro` · `null` | —         | Cómo aceptó realmente la persona. `en_persona` = en persona o en el punto de venta; `telefono` = por teléfono, registrado por quien tomó la llamada; `email` = por correo o un formulario web; `escrito` = en papel, firmado; `otro` = otra cosa, dicho tal cual en vez de forzarlo al que más se parezca. La política de WhatsApp es que tener el número no es consentimiento —«se requiere una acción de opt-in afirmativa y explícita»—, así que una atestación sin método se rechaza con `400 optin_method_required`. |
| `opt_in_attested_by` | string                                                            | —         | Quién recogió el consentimiento. Por defecto, la credencial que hizo la llamada.                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **Respuestas**       |                                                                   |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo              |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `201`     | The contact.                                                                                                                                                                                                                                                                                                              | CounterpartyContact |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse       |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse       |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse       |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse       |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse       |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse       |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse       |

## `PATCH /empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts/{contact_id}` [#patch-empresas-empresa-id-counterparties-counterparty-rut-contacts-contact-id]

**Edit a contact, promote it, or record an opt-out**

`primary: true` degrada al que lo tuviera, en la misma llamada: sólo un contacto por contraparte puede ser principal y eso lo impone la base de datos.

`opted_out: true` registra que la persona pidió parar por otro canal. `opted_out: false` no existe: un contacto dado de baja queda congelado y no se puede editar, ni volver a atestar, ni reactivar. A quien pidió que no le escriban no lo des-pide un colega arreglándole el nombre.

```bash
curl -sS -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut}/contacts/{contact_id} \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"cliente — Comercial Andina","phone":"…"}'
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |
| `contact_id`       | path | sí        | string | The `cnt_…` id.                                                                                                                                                                                              |

**Cuerpo**

| Campo               | Tipo                                                              | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------- | ----------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`              | string                                                            | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `phone`             | string                                                            | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `counterparty_name` | string,null                                                       | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `primary`           | boolean                                                           | —         | `true` degrada al que lo tenga ahora, en la misma llamada. Dos principales no pueden existir ni por un instante.                                                                                                                                                                                                                                                                                                                                                                                                          |
| `opt_in`            | boolean                                                           | —         | `false` borra la atestación: un registro de consentimiento al que sólo se le puede agregar es peor para la persona a la que ese registro protege.                                                                                                                                                                                                                                                                                                                                                                         |
| `opt_in_method`     | `en_persona` · `telefono` · `email` · `escrito` · `otro` · `null` | —         | Cómo aceptó realmente la persona. `en_persona` = en persona o en el punto de venta; `telefono` = por teléfono, registrado por quien tomó la llamada; `email` = por correo o un formulario web; `escrito` = en papel, firmado; `otro` = otra cosa, dicho tal cual en vez de forzarlo al que más se parezca. La política de WhatsApp es que tener el número no es consentimiento —«se requiere una acción de opt-in afirmativa y explícita»—, así que una atestación sin método se rechaza con `400 optin_method_required`. |
| `opted_out`         | boolean                                                           | —         | `true` registra que la persona pidió parar por otro canal. `false` no se acepta: una baja no se revierte por esta API.                                                                                                                                                                                                                                                                                                                                                                                                    |
| **Respuestas**      |                                                                   |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo              |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `200`     | El contacto actualizado.                                                                                                                                                                                                                                                                                                  | CounterpartyContact |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse       |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse       |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse       |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse       |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse       |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse       |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse       |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse       |

## `DELETE /empresas/{empresa_id}/counterparties/{counterparty_rut}/contacts/{contact_id}` [#delete-empresas-empresa-id-counterparties-counterparty-rut-contacts-contact-id]

**Sacar un contacto de la agenda**

204 haya existido o no. La excepción es un contacto dado de baja, que se conserva: su fila es justo lo que permite negarse a volver a agregar el mismo número.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/counterparties/{counterparty_rut}/contacts/{contact_id} \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro          | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                        |
| ------------------ | ---- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `empresa_id`       | path | sí        | string |                                                                                                                                                                                                              |
| `counterparty_rut` | path | sí        | Rut    | El RUT de la contraparte, canónico (`76000002-7`). Es la clave de la relación y de la entrada en la libreta de direcciones — una contraparte no tiene id propio, porque hay exactamente una de cada por RUT. |
| `contact_id`       | path | sí        | string | The `cnt_…` id.                                                                                                                                                                                              |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Removed.                                                                                                                                                                                                                                                                                                                  | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/onboarding` [#get-empresas-empresa-id-onboarding]

**Ciclo de vida de la puesta en marcha, sus pasos y las acciones humanas que la bloquean**

Todo lo que un asistente necesita para dibujar el avance y decirle a la persona qué hacer ahora.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                                             |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| `200`     | Estado de la puesta en marcha.                                                                                                                                                                                                                                                                                            | [Onboarding](/docs/referencia/esquemas#onboarding) |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                                      |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                                      |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse                                      |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                                      |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                                      |

## `POST /empresas/{empresa_id}/onboarding/links` [#post-empresas-empresa-id-onboarding-links]

**Acuna un enlace a una pagina alojada para el representante legal**

La persona que tiene que actuar muchas veces no es la que tiene la cuenta: la cuenta es del
contador, el certificado es de un socio, y los pasos del SII que necesitan a una persona son
del socio. Por eso las páginas alojadas se alcanzan con un enlace, no con un inicio de
sesión.

`step` es cualquier paso del checklist de ESTA empresa que necesite a una persona -
`actor: customer` (el paso lo hace ella) O `stall_actor: customer` (un paso NUESTRO que no
puede terminar hasta que ella decida). Cuáles existen depende de su `certification_track`:
`certificate`, `sii_postulacion`, `cumplimiento` y `habilitacion` en el catálogo mercado;
`credential`, `clave_centralizado` y `usuario_autorizado` en el SFG. Un paso del otro
catálogo se rechaza con un `400` nombrando los que esta empresa sí tiene. El enlace del
mandato es de un solo uso y viene de
`POST /empresas/\{empresa_id\}/mandato` con cuerpo vacío en su lugar..

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/links \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"step":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo          | Tipo        | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------- | ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `step`         | string      | sí        | Qué página alojada abre el enlace: cualquier paso del checklist de ESTA empresa que necesite a una persona — `actor: customer` (la ejecuta ella) o `stall_actor: customer` (la ejecutamos nosotros y espera su decisión). `mandato` está deliberadamente ausente: su enlace es de un solo uso y sale de `POST /empresas/\{empresa_id\}/mandato` con el cuerpo vacío. Los valores válidos se leen de `GET /empresas/\{empresa_id\}/onboarding`.                                                                                                                                                                                                      |
| `requested_by` | RequestedBy | —         | Quién pide este enlace, según TÚ te describes (2026-09, #459). Opcional, y se le muestra a la persona que recibe el enlace: «Este enlace lo pidió Claude Desktop el 4 de septiembre» en vez de «lo generó una integración o un agente en nombre de tu cuenta», que era la única frase disponible para todos los agentes que han existido. ES UNA AFIRMACIÓN, NO UNA CREDENCIAL. No cambia nada sobre la autorización y nunca se cree para tomar una decisión; la credencial con la que llegó tu petición se registra aparte. Manda `\{"kind": "agent", "name": "&lt;el nombre de tu cliente&gt;"\}` cuando seas un agente actuando por una persona. |
| **Respuestas** |             |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo         |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
| `201`     | El enlace. La `url` lleva el token y no se vuelve a mostrar.                                                                                                                                                                                                                                                              | OnboardingLink |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse  |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse  |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse  |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse  |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse  |

## `DELETE /empresas/{empresa_id}/onboarding/links/{step}` [#delete-empresas-empresa-id-onboarding-links-step]

**Revoca un enlace alojado del representante legal**

204 aunque no hubiera enlace. Un enlace revocado responde igual que uno inexistente,
para que nadie pueda averiguar con un token si alguna vez le pedimos a una empresa que
firmara algo.

```bash
curl -sS -X DELETE https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/links/{step} \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas                                                                                                                                                                                                                                                     |
| ------------ | ---- | --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `empresa_id` | path | sí        | string |                                                                                                                                                                                                                                                           |
| `step`       | path | sí        | string | El paso cuyo enlace se está revocando. Cualquier paso para el que cualquiera de los dos catálogos pueda acuñar un enlace - el conjunto amplio es intencional, para que un enlace acuñado bajo un checklist que la empresa ya dejó igual se pueda revocar. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `204`     | Revocado.                                                                                                                                                                                                                                                                                                                 | —             |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/onboarding/go_live` [#post-empresas-empresa-id-onboarding-go-live]

**Pide al titular que apruebe la puesta en marcha, o declara la decisión en su nombre**

La Declaracion de Cumplimiento no es un avance: es una decision sobre un mes. Al
declarar, la empresa "queda operando automaticamente en el sistema de facturacion
electronica" y debe enviar la Informacion Electronica de Compras y Ventas DESDE EL MES
DE LA DECLARACION, emita o no. La propia pagina del SII dice que el paso se puede
postergar.

Ese mes lo elige el cliente y un mandato de custodia no lo carga: el motor exige esta
autorizacion ADEMAS de su propio interruptor interno.

Manda `\{"authorized": false\}` para retirarla mientras no se haya presentado. Una vez
presentada la declaracion no queda nada que retirar y la llamada se rechaza con
`409 cumplimiento_already_filed`.

**LA AUTORIZACIÓN ES GRATIS** (2026-09-04, #530). Antes se cobraba, y solo en esta puerta: la
página alojada de `cumplimiento` para el representante legal respondía `200` para la misma
empresa sin suscripción, así que la regla vivía en un solo canal y un agente que mandaba al
humano por la otra puerta la esquivaba. Es una DECISIÓN, no una emisión — el titular diciendo
«que mi obligación empiece este mes» — y la puerta de cobro está donde está el valor: todo acto
que gasta un folio o sale del edificio sigue cobrado, así que una empresa autorizada que no ha
pagado no emite nada. Esta operación ya no responde `402`.

**TIENE QUE HABER UNA DECISIÓN (2026-09, #451).** Acuñar un enlace de aprobación para una
empresa que todavía no llega a la Declaración de Cumplimiento le entregaba a una persona una
página sin nada. Ahora hay dos rechazos que van primero, antes de los bloqueadores y antes del
acuñe:

* `409 go_live_not_ready` — el carril de mercado aún no llega a la decisión.
  `error.details.blocked_on` dice qué paso lo está deteniendo y `error.details.next` es el
  `\{method, url\}` que avisa cuando se mueve. Reintentable: va a estar listo.
* `409 go_live_not_applicable` — esta empresa no se está certificando para mercado, así que no
  tiene Declaración de Cumplimiento. Lo que abre la emisión de una empresa SFG es la
  `puesta_en_vivo`, que es nuestra. No reintentable.

Ninguno aplica a `\{"authorized": false\}`: una decisión que existe siempre se puede retirar,
haya hecho lo que haya hecho el carril desde entonces.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/go_live \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"authorized":true}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo          | Tipo    | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------- | ------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorized`   | boolean | —         | Si está presente, declara la decisión en nombre del titular - una *atestación*, detrás de `onboarding:attest`. `false` retira una autorización sobre la que todavía no se actuó; una vez presentada la declaración el llamado se rechaza con `409 cumplimiento_already_filed`. &#x2A;*Sin default.** Omite todo el cuerpo para acuñar un enlace de aprobación para el titular en su lugar. Antes tenía `true` por defecto, lo que significaba que quien no enviaba cuerpo autorizaba en silencio una consecuencia tributaria. |
| **Respuestas** |         |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo              |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `200`     | La autorización, tal como está ahora. Se responde para la forma con cuerpo.                                                                                                                                                                                                                                               | GoLiveAuthorization |
| `201`     | El enlace de aprobación, respondido para un cuerpo vacío. `approval_url` se muestra una sola vez.                                                                                                                                                                                                                         | GoLiveApproval      |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse       |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse       |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse       |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse       |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse       |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse       |

## `POST /empresas/{empresa_id}/onboarding/steps/{step}/recheck` [#post-empresas-empresa-id-onboarding-steps-step-recheck]

**Avísanos que una persona hizo su paso, y vamos a mirar**

La mitad de reanudación del traspaso de `pending_action`. Una persona realizó uno de los actos
que la ley chilena le reserva (ver `pending_action.performed_by`), y esto nos pide averiguar si
el SII está de acuerdo.

**Este endpoint acepta una afirmación y no produce ningún hecho.** No recibe cuerpo, no escribe
ningún status de paso y no mueve ninguna empresa. Lo que hace es encolar al productor que LEE el
SII, más el tick que integra lo que ese productor encuentre, y devuelve el status del paso tal
como estaba en el momento del llamado — leído antes de encolar y devuelto sin cambios. Si haces
un recheck sobre un paso `action_required` y te devuelve `action_required`, el endpoint está
funcionando bien: el paso avanza cuando vemos el hecho, no cuando tú lo dices. `verified` va en
la respuesta y siempre es `false`.

`evidence_source` dice cómo (o si) el paso se puede confirmar. `sii_probe` significa que vamos
y leemos el SII. `own_record` significa que el acto queda en nuestras propias tablas y lo vamos
a ver. `no_producer` significa que este build genuinamente todavía no puede observar ese paso —
la `habilitacion` de boletas es el caso — y `contact` nombra la salida:
`POST .../onboarding/steps/\{step\}/attest` (#395), que es un endpoint DISTINTO que sí escribe un
hecho en vez de solo registrar una afirmación. No le digas a un usuario que este llamado por sí
solo está observando un paso `no_producer`; no es así.

`queued` y `already_queued` separan los trabajos que este llamado creó de los que ya estaban
programados para la misma ventana de cinco minutos. Ambos significan «estamos por mirar».

Para una empresa de prueba no se encola nada y `evidence_source` es `sandbox`: el onboarding de
una empresa de prueba nunca abre sesión contra el SII, así que no hay nada que volver a leer.
Mueve sus pasos con los test helpers en su lugar.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/steps/{step}/recheck \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas                                                                    |
| ------------ | ---- | --------- | ------ | ------------------------------------------------------------------------ |
| `empresa_id` | path | sí        | string |                                                                          |
| `step`       | path | sí        | string | Una clave de paso de la lista de puesta en marcha de esta misma empresa. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                                                           |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `202`     | La declaración se aceptó para verificación. Todavía no se ha verificado nada.                                                                                                                                                                                                                                             | [OnboardingRecheck](/docs/referencia/esquemas#onboardingrecheck) |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse                                                    |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse                                                    |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse                                                    |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse                                                    |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse                                                    |

## `POST /empresas/{empresa_id}/onboarding/steps/{step}/attest` [#post-empresas-empresa-id-onboarding-steps-step-attest]

**Registra que una persona realizó un paso que este build no puede comprobar por sí solo (#395)**

El campo `contact` de `recheck` apunta acá cuando `evidence_source: 'no_producer'`. A
diferencia de `recheck` — que acepta una afirmación y no produce ningún hecho — **este
endpoint sí escribe uno**: una fila en `sii_onboarding_evidence` que el siguiente tick de
onboarding lee como el hecho que permite que el paso se complete.

Se rechaza con `422 invalid_field` en cualquier paso cuyo `evidence_source` no sea
`no_producer` — atestiguar un paso que la sonda del SII o nuestros propios registros ya
confirman sería una segunda fuente de verdad compitiendo por un hecho que ya podemos
verificar. `habilitacion` (habilitación de boletas en `certBolElectDteInternet`, una SPA del
SII que no capturamos) es el único paso que este mapa marca como `no_producer` hoy.

Requiere `onboarding:attest` **por sí mismo**: nunca en el set por defecto del bootstrap,
nunca implicado por `empresas:write` solo (ADR-0012 §3-4). `attested_by` es obligatorio —
quién te contó que esto pasó.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/steps/{step}/attest \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"attested_by":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas                                                                    |
| ------------ | ---- | --------- | ------ | ------------------------------------------------------------------------ |
| `empresa_id` | path | sí        | string |                                                                          |
| `step`       | path | sí        | string | Una clave de paso de la lista de puesta en marcha de esta misma empresa. |

**Cuerpo**

| Campo          | Tipo   | Requerido | Notas                                                                      |
| -------------- | ------ | --------- | -------------------------------------------------------------------------- |
| `attested_by`  | string | sí        | Un nombre, o el RUT del representante legal. Quién te contó que esto pasó. |
| `note`         | string | —         |                                                                            |
| **Respuestas** |        |           |                                                                            |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `202`     | Se registró la atestación. El paso se integra en el próximo tick.                                                                                                                                                                                                                                                         | OnboardingAttestation |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse         |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse         |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse         |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse         |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse         |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse         |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse         |

## `POST /empresas/{empresa_id}/onboarding/steps/{step}/approve` [#post-empresas-empresa-id-onboarding-steps-step-approve]

**Registrar la autorización del titular para un paso que después ejecutamos nosotros (#452, #453)**

El hermano de `attest`, para la situación opuesta. `attest` dice «una persona hizo algo que
no podemos ver»; éste dice «una persona autorizó algo que vamos a hacer NOSOTROS».

Dos actos de este pipeline son nuestros de ejecutar en cuanto alguien elige el momento. La
postulación se presenta con el certificado del representante legal que tenemos en custodia,
bajo la cláusula 4.2 a) del mandato, y le cuesta a una empresa del Sistema de Facturación
Gratuito su «calidad de usuario activo» en cuanto el SII la autoriza. La habilitación de
boletas abre un reloj de 24 horas del SII. Ninguna de las dos es una decisión que un mandato
de custodia lleve puesta, así que cada una espera una fila en
`sii_onboarding_step_approvals`.

**El `act` tiene que ser el que el paso está pidiendo ahora.** Lee
`steps[].pending_action.approval` en `GET .../onboarding`: dice cuál es el acto, de quién es
la decisión, las consecuencias que hay que mostrar primero y las dos etiquetas de botón. Un
paso que no está pidiendo nada responde `409 onboarding_approval_not_offered`; un `act` que
no calza responde `400 invalid_field`. Un mismo paso lleva decisiones distintas en momentos
distintos, y una aprobación registrada contra el acto equivocado es consentimiento que nadie
dio.

**Un rechazo se registra, no se ignora.** `decision: "reject"` escribe una fila igual que una
aprobación, así el producto puede decir «lo dejaste para después» en vez de «nadie
contestó». Los ejecutores leen la fila MÁS RECIENTE del acto y ramifican por `decision`.

Exige `onboarding:attest` en sí mismo — nunca en el set por defecto del bootstrap, nunca
implicado por `empresas:write` (ADR-0012 §3-4). La forma canónica de una aprobación es la
página alojada (`POST /onboarding/steps/\{step\}/approve` con el token del enlace); ésta es la
puerta del integrador que recogió la decisión en su propio flujo.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/steps/{step}/approve \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"act":"…","decision":"approve"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas                                                                    |
| ------------ | ---- | --------- | ------ | ------------------------------------------------------------------------ |
| `empresa_id` | path | sí        | string |                                                                          |
| `step`       | path | sí        | string | Una clave de paso de la lista de puesta en marcha de esta misma empresa. |

**Cuerpo**

| Campo          | Tipo                 | Requerido | Notas                                                                                     |
| -------------- | -------------------- | --------- | ----------------------------------------------------------------------------------------- |
| `act`          | string               | sí        | El acto que se está decidiendo, exactamente como lo nombra `pending_action.approval.act`. |
| `decision`     | `approve` · `reject` | sí        |                                                                                           |
| `note`         | string               | —         |                                                                                           |
| **Respuestas** |                      |           |                                                                                           |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `201`     | La decisión quedó registrada. Con `approve` se encola el tick que la pliega.                                                                                                                                                                                                                                              | OnboardingStepApproval |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse          |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse          |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse          |
| `404`     | No existe ese objeto bajo esta llave.                                                                                                                                                                                                                                                                                     | ErrorResponse          |
| `409`     | Conflicto de estado: reutilización de idempotencia, `external_id` duplicado o artefacto no listo.                                                                                                                                                                                                                         | ErrorResponse          |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse          |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse          |

## `GET /empresas/{empresa_id}/onboarding/certification` [#get-empresas-empresa-id-onboarding-certification]

**El set de pruebas: qué se cargó, qué falta y qué contestó el SII**

Una sola lectura, no cuatro. Una certificación es acotada —un archivo de set, un documento de
datos, un puñado de envíos en a lo más tres rondas— y partirla haría que la pantalla obvia costara
cuatro viajes cuyas respuestas pueden contradecirse.

DOS CAMPOS QUE SE PARECEN Y SON OPUESTOS. `envios[].estado` es el estado del ENVÍO, donde «SOK»
quiere decir «envío recibido»: llegó, nadie lo ha juzgado. `envios[].verdict` es el veredicto del
SET, donde «SOK» quiere decir APROBADO. Las mismas tres letras, consecuencias contrarias, y por eso
son dos campos y nunca uno.

`envios[].dry_run: true` significa que el sobre se construyó y NO se envió. `submittable` es `null`
mientras no haya habido ninguna construcción, que no es lo mismo que `false`.

`problems[].message` puede venir en `null`: las frases viven en el registro de la construcción, al
lado del artefacto, y cuando no se puede leer la respuesta se degrada a los códigos en vez de
fallar. El código siempre está.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/certification \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | The certification, as it now stands.                                                                                                                                                                                                                                                                                      | Certification |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `POST /empresas/{empresa_id}/onboarding/certification/set_file` [#post-empresas-empresa-id-onboarding-certification-set-file]

**Sube el set de pruebas que el SII emitió para esta empresa**

El SII emite el `.txt` del set por contribuyente cuando acepta la postulación. Nadie lo descarga
por ti; ésta es la puerta por donde entran los bytes.

MULTIPART, NO BASE64 EN JSON. El archivo viene en ISO-8859-1 y sus acentos son parte del documento:
«Cajón» y «Pañuelo» son dos de los ítems que el SII reparó cuando se perdieron los suyos. Multipart
nos entrega los BYTES; un string JSON ya habría pasado por la idea que alguien tenga de una
codificación para cuando lo viéramos, y el daño no se ve hasta que una ronda vuelve rechazada. Los
bytes se guardan tal cual y nunca se recodifican. Tope: 1 MB.

Unos bytes que no son un set de pruebas se rechazan con `422 set_file_unrecognized` y NO se guarda
nada: una página de login del portal guardada como «el set» reportaría una empresa con cero casos,
que no es lo mismo que una empresa sin archivo.

Un set que SÍ se reconoce se guarda aunque haya partes que no entendimos; ésas vienen en
`problems[]`.

Este endpoint no corre una ronda, no abre un socket contra el SII y no gasta un folio. La ronda es
del motor, en su propio reloj.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/certification/set_file \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -F "file=…"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo (multipart/form-data)**

| Campo          | Tipo   | Requerido | Notas                                                      |
| -------------- | ------ | --------- | ---------------------------------------------------------- |
| `file`         | string | sí        | The `.txt` as the SII issued it. ISO-8859-1, at most 1 MB. |
| **Respuestas** |        |           |                                                            |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `201`     | The set as we read it.                                                                                                                                                                                                                                                                                                    | CertificationSetFile |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse        |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse        |
| `422`     | Bien formado pero viola una regla del dominio: folios agotados, ventana de acuse cerrada.                                                                                                                                                                                                                                 | ErrorResponse        |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse        |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse        |

## `POST /empresas/{empresa_id}/onboarding/certification/inputs` [#post-empresas-empresa-id-onboarding-certification-inputs]

**Entrega los datos que el set de pruebas no trae**

El set enuncia varias cosas por implicación y no deletrea ninguna: quién emitió cada compra del
libro, qué dice la corrección del caso CodRef-2, qué factura facturó la guía que el set marca
«facturada», el factor de proporcionalidad, el folio de notificación que emitió el SII y —para una
ronda de boletas— las unidades abreviadas y diez boletas de todos los días. Cada una es una negativa
deliberada del constructor, porque la alternativa es un documento que el SII rechaza con el folio ya
gastado.

LA MEZCLA ES POR RANURA DE PRIMER NIVEL: ausente conserva, `null` borra, presente REEMPLAZA ENTERA.
Reenviar `proveedores` los reenvía todos —que es lo que manda un formulario y la única forma de
BORRAR uno—. Una mezcla profunda dejaría la fila que quisiste borrar en el próximo libro.

NO SE ESCRIBE NADA SI ALGO NO VALIDA, ni siquiera la mitad buena: una escritura parcial deja a la
empresa en un estado que nadie pidió y una ronda que se niega por algo que crees haber arreglado.
`400 certification_input_invalid` trae TODOS los problemas en `error.details.problems`, no el
primero. También puede negarse por un valor que no mandaste, cuando el documento guardado sobre el
que se mezcla ya era inválido.

UNA RANURA VIENE PRELLENADA: `libro_guias.folio_notificacion` vale 3 por defecto, el número que
continúa el 1 y el 2 del libro de ventas y el de compras. LibroGuia\_v10.xsd hace obligatorio el
elemento donde el del IECV es opcional, así que no se puede omitir, y una ronda que sale con el
valor por defecto lo dice en un aviso. `libro_boleta_folio_notificacion` no tiene default ni lo va a
tener: es un número que el SII emite para una notificación concreta y nada puede deducirlo.

```bash
curl -sS -X POST https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/certification/inputs \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"receptor":{"rut":"76543212-K"},"giro_recep_emisor":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                             | Tipo         | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------------- | ------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `receptor`                        | object,null  | —         | La parte a la que se emiten los documentos de prueba. El `giro` se mide contra `GiroRecep` (40), que es más corto que `GiroEmis` (80): el propio giro de un emisor es frecuentemente ilegal en esta ranura.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `giro_recep_emisor`               | string,null  | —         | Una abreviación de a lo más 40 caracteres del giro del propio EMISOR, para el ÚNICO lugar en que una guía de traslado interno lo vuelve a escribir: el receptor es el emisor mismo (un traslado interno mueve bienes entre las propias dependencias de la empresa), así que su giro es lo que se escribiría en `GiroRecep` — que topa en 40 donde el propio `GiroEmis` del emisor permite 80. Ausente, y el giro del emisor cabe en 40 caracteres de todas formas: se escribe tal cual, como siempre. Ausente, y no cabe: `GiroRecep` es opcional en el esquema, así que el elemento se OMITE en vez de recortarse, y la ronda levanta `giro_recep_omitted` para que la omisión sea visible en vez de silenciosa — éste es exactamente el reparo que el SII hizo sobre el giro de 65 caracteres del piloto. Presente: se escribe tal cual, y se rechaza — nunca se recorta — si tampoco cabe. |
| `text_correction`                 | object,null  | —         | La corrección CodRef-2. Se escribe «Dice: \{says} y debe decir: \{shouldSay}» dentro de `RazonRef`, que topa en 90; 21 de esos caracteres son el andamiaje, así que las dos mitades comparten 69. Se mide sobre la COMPOSICIÓN, y nunca se recorta por ti.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `proveedores`                     | object,null  | —         | Quién emitió cada compra, con la clave `&lt;tipoDte&gt;:&lt;folio&gt;` — las dos cosas que el set imprime para cada fila. Un RUT cuyo dígito verificador falla módulo 11 es una de las dos causas documentadas de un libro «Descuadrado», y se descubre cuando los folios ya se gastaron. La `razonSocial` se mide contra el `RznSoc` del LIBRO (50), no contra los 100 del DTE.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `iva_no_rec_codes`                | object,null  | —         | Por qué una compra pierde su crédito. LibroCV\_v10.xsd enumera 1, 2, 3, 4 y 9.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `libro_treatments`                | object,null  | —         | El tratamiento de IVA de una compra que el set no clasifica. «unknown» es la palabra del planificador para «el set no dijo nada» y «exento\_sin\_iva» es aritmética, así que ninguna de las dos es un dato que se declare.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `libro_guias`                     | object,null  | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `factor_proporcionalidad`         | number,null  | —         | El set lo imprime como «EL FACTOR DE PROPORCIONALIDAD DEL IVA ES DE 0.60». Decide cuánto crédito se reclama, así que nunca se adivina.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `libro_boleta_folio_notificacion` | integer,null | —         | El «Folio de la Notificación con que se Solicita el Libro Especial», que emite el SII. SIN VALOR POR DEFECTO, y no lo va a tener: nada puede deducirlo, y una ronda de boletas se niega sin él.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `boleta_unidades`                 | object,null  | —         | `UnmdItem` por `&lt;casoId&gt;:&lt;nroLinDet&gt;`, para lo único que un set puede exigir y su propio esquema prohibir: una unidad de más de cuatro caracteres. Se rechaza, nunca se recorta — «mens» no es una unidad.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `boleta_muestras`                 | array,null   | —         | Las diez boletas de todos los días que pide la revisión de boletas del SII, que describen lo que esta empresa vende de verdad a los precios que cobra de verdad. Menos de diez es una solicitud incompleta y se rechaza; más está bien.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `permiso_usuario_rut`             | string,null  | —         | La persona natural por la que la sonda de permisos pregunta en «Mantención de usuarios», cuando el certificado que custodiamos no trae ningún RUT propio. LA ÚNICA RANURA DE ESTA LISTA QUE NO ES UN DATO DE UN DOCUMENTO, y la única que ningún constructor lee. El estado 106 «Usuario sin permiso de envío» es sobre el RUT para el que se acuñó el token del SII, así que la sonda lo lee primero del certificado y sólo recurre a éste. Su ausencia NO rechaza una ronda: la ronda igual se construye y se firma, y lo que se estaciona es la compuerta de permisos, que reporta `no_target` con el remedio adjunto. Se valida módulo 11 como todo RUT acá. `null` lo borra. Nunca el RUT de la propia empresa: esa tabla lista personas naturales, así que un RUT de empresa no encontraría a nadie y reportaría al remitente como no listado.                                          |
| **Respuestas**                    |              |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | Los datos, tal como quedan ahora en la empresa.                                                                                                                                                                                                                                                                           | object        |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/onboarding/evidence` [#get-empresas-empresa-id-onboarding-evidence]

**La rendicion de cuentas: lo que hicimos por la empresa ante el SII**

La clausula 4.4 del mandato nos obliga a rendir cuenta de lo que hicimos por el
cliente. Cada acto del proceso de puesta en marcha queda como artefacto, y esto los
devuelve, del mas reciente al mas antiguo.

`retention_until` viene en CADA fila y son seis anos desde el acto: prescripcion
extraordinaria del Codigo Tributario y deber de conservacion, que es ademas la
finalidad de retencion bajo la Ley 21.719. Ante una revocacion o un traspaso el
registro se congela en solo lectura y se ofrece como exportacion; nunca se purga antes.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/evidence \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En    | Requerido | Tipo    | Notas                                                            |
| ------------ | ----- | --------- | ------- | ---------------------------------------------------------------- |
| `empresa_id` | path  | sí        | string  |                                                                  |
| `limit`      | query | —         | integer |                                                                  |
| `cursor`     | query | —         | string  | Cursor opaco tomado del `next_cursor` de una respuesta anterior. |
| `step`       | query | —         | string  | Solo los artefactos de este paso.                                |
| `kind`       | query | —         | string  | Solo los artefactos de este tipo.                                |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo                      |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `200`     | Los artefactos.                                                                                                                                                                                                                                                                                                           | lista de OnboardingEvidence |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse               |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse               |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse               |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse               |

## `GET /empresas/{empresa_id}/onboarding/evidence/export` [#get-empresas-empresa-id-onboarding-evidence-export]

**La rendicion de cuentas como un solo archivo CSV**

Las mismas filas que sirve el listado, completas en una sola respuesta, como un archivo
que le puedes pasar a un cliente, a su contador o a un abogado. La resolucion de
retencion dice que ante una revocacion o un traspaso se ofrece al cliente una
exportacion completa como rendicion formal de la clausula 4.4; esta es esa exportacion,
y esta disponible en cualquier momento, no solo a la salida.

RFC 4180, separado por comas, UTF-8 SIN marca de orden de bytes, saltos CRLF. Las
columnas son los propios campos del objeto JSON en el mismo orden: `id`, `empresa_id`,
`step`, `tipo_dte`, `kind`, `captured_at`, `retention_until`, `sha256`, `bytes`,
`content_type`, `detail`. Asi que `storage_path` tampoco sale aca, igual que no sale
alla. `detail` viaja como su JSON compacto, entre comillas.

Se pagina internamente y se corta en 50.000 filas. Cuando llega al tope la respuesta lo
dice en `Facturia-Export-Complete: false` en vez de servir un archivo truncado que
parece entero; `step` y `kind` son la forma de acotar una exportacion que llego al tope.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/onboarding/evidence/export \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En    | Requerido | Tipo   | Notas                             |
| ------------ | ----- | --------- | ------ | --------------------------------- |
| `empresa_id` | path  | sí        | string |                                   |
| `step`       | query | —         | string | Solo los artefactos de este paso. |
| `kind`       | query | —         | string | Solo los artefactos de este tipo. |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | La rendicion, como archivo CSV adjunto.                                                                                                                                                                                                                                                                                   | text/csv      |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `GET /empresas/{empresa_id}/automation_settings` [#get-empresas-empresa-id-automation-settings]

**Devuelve las automatizaciones de la empresa**

Los interruptores de emisión automática de la empresa (`auto_characterize_purchases`, `auto_emit_46`, …), cada uno con su valor por defecto donde no se ha fijado.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/automation_settings \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo             |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `200`     | Las automatizaciones.                                                                                                                                                                                                                                                                                                     | AutomationSettings |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse      |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse      |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse      |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse      |

## `PATCH /empresas/{empresa_id}/automation_settings` [#patch-empresas-empresa-id-automation-settings]

**Actualiza las automatizaciones de la empresa**

Toda automatización viene apagada salvo `auto_request_folios`. `auto_emit_46` y
`auto_file_f29` se activan empresa por empresa y con tope.

```bash
curl -sS -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/automation_settings \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"object":"…","empresa_id":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                             | Tipo                                     | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| --------------------------------- | ---------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `object`                          | string                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `empresa_id`                      | string                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `auto_emit_46`                    | boolean                                  | —         | Por defecto: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `auto_emit_46_max_amount`         | Clp                                      | —         | Monto en CLP. Pesos enteros, nunca decimales ni strings.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `auto_file_f29`                   | boolean                                  | —         | Por defecto: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `auto_file_f29_day`               | integer                                  | —         | Por defecto: `18`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `auto_file_f29_max_payable`       | Clp                                      | —         | Por defecto 0 — de fábrica solo se declara sola una posición en cero o a favor, y cualquier mes en que efectivamente debas IVA espera a una persona. Súbelo a propósito, empresa por empresa. Por defecto: `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `auto_request_folios`             | boolean                                  | —         | Por defecto: `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `auto_request_folios_threshold`   | integer                                  | —         | Por defecto: `50`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `auto_accept_received`            | boolean                                  | —         | Por defecto: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `auto_accept_received_after_days` | integer,null                             | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `require_confirmation`            | boolean                                  | —         | Cuando está en true, las acciones que mueven plata iniciadas desde una superficie de agente — emitir un documento, declarar un F29, registrar un reclamo con las herramientas del servidor MCP — exigen un paso doble borrador → confirmación en vez de ejecutarse en la primera llamada. Existe sobre todo para la superficie MCP; la API REST que describe este documento no cambia, y la bandera vive en este recurso para que un solo objeto de configuración gobierne la empresa en toda superficie. Por defecto: `false`.                                                                                                                             |
| `rcv_sync_frequency`              | `hourly` · `daily` · `weekly` · `manual` | —         | Por defecto: `"daily"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `honor_estado_contable_override`  | boolean                                  | —         | Si la propuesta de F29 obedece al `estado_contable_override` LOCAL, fijado con `POST /tax/purchases/\{entry_id\}/estado_contable`, en vez del `estado_contable` que entregó el registro del propio SII. Viene apagado por defecto, y la dirección de ese default es el punto: solo las compras en `REGISTRO` traen crédito fiscal, así que un cambio local de `PENDIENTE` a `REGISTRO` reclama un IVA que el SII no reconoce — y el valor del SII es el que lee una fiscalización. Encendido, cada propuesta afectada lleva una observación explícita que nombra los documentos, y cada escritura queda en la bitácora del documento. Por defecto: `false`. |
| `updated_at`                      | string                                   | —         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Respuestas**                    |                                          |           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo             |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `200`     | Las automatizaciones actualizadas.                                                                                                                                                                                                                                                                                        | AutomationSettings |
| `400`     | Entrada mal formada o incompleta.                                                                                                                                                                                                                                                                                         | ErrorResponse      |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse      |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse      |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse      |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse      |

## `GET /empresas/{empresa_id}/branding` [#get-empresas-empresa-id-branding]

**Lee el logo, el formato de impresión por defecto y el texto del pie**

Cada campo viene rellenado con los valores de plataforma donde la empresa no fijó nada, así que el objeto siempre describe cómo se va a ver un PDF de verdad y no solo lo que sobrescribiste.

```bash
curl -sS https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/branding \
  -H "Authorization: Bearer $FACTURIA_KEY"
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Respuestas**

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | The empresa's branding.                                                                                                                                                                                                                                                                                                   | Branding      |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |

## `PATCH /empresas/{empresa_id}/branding` [#patch-empresas-empresa-id-branding]

**Actualiza el logo, el formato de impresión por defecto y el pie de página**

Actualiza los campos de marca del panel y las páginas alojadas (logo, colores, nombre de exhibición). Un campo desconocido se rechaza (`422 unknown_setting`), nunca se ignora en silencio.

```bash
curl -sS -X PATCH https://api.facturia.cl/v1/empresas/emp_01K2R6ZC4P8QW1VN7T3MHDY9EK/branding \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"object":"…","logo_url":"…"}'
```

**Parámetros**

| Parámetro    | En   | Requerido | Tipo   | Notas |
| ------------ | ---- | --------- | ------ | ----- |
| `empresa_id` | path | sí        | string |       |

**Cuerpo**

| Campo                | Tipo    | Requerido | Notas                                                                                                                                                                                                                                                                                                                                                                                    |
| -------------------- | ------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `object`             | string  | —         |                                                                                                                                                                                                                                                                                                                                                                                          |
| `logo_url`           | string  | —         |                                                                                                                                                                                                                                                                                                                                                                                          |
| `default_pdf_format` | `carta` | —         | `carta` es el único valor válido — `80mm` fue retirado en la wave 9 junto con el parámetro `format`, y no existe layout térmico. `PATCH` rechaza cualquier otro valor con `400 invalid_field` (ticket #18 wave 10). No queda nada más que seleccionar: ya nombra el único layout que esta API renderiza, así que validarlo es lo que significa "aplicarlo". Por defecto: `"carta"`.      |
| `cedible_by_default` | boolean | —         | Aplica a las facturas — tipo 33 y 34 (Ley 19.983; no "solo tipo 33", corregido en el ticket #18 wave 10). La consume la resolución de copia por defecto de `GET /documents/\{document_id\}/pdf`: un `pdf.cedible` propio del documento (§9.3) la anula; un `?copy=` explícito anula a ambos. Ver el parámetro `copy` de ese endpoint para la precedencia completa. Por defecto: `false`. |
| `footer_text`        | string  | —         |                                                                                                                                                                                                                                                                                                                                                                                          |
| **Respuestas**       |         |           |                                                                                                                                                                                                                                                                                                                                                                                          |

| Código    | Significado                                                                                                                                                                                                                                                                                                               | Cuerpo        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `200`     | La marca actualizada.                                                                                                                                                                                                                                                                                                     | Branding      |
| `401`     | Llave ausente, mal formada o revocada.                                                                                                                                                                                                                                                                                    | ErrorResponse |
| `403`     | Llave válida pero sin permiso: scope, lista blanca de empresas o modo.                                                                                                                                                                                                                                                    | ErrorResponse |
| `429`     | Demasiadas solicitudes.                                                                                                                                                                                                                                                                                                   | ErrorResponse |
| `default` | Un error no enumerado aparte para esta operación, en el mismo sobre §5.5 que cualquier otro rechazo. Ramifica por `error.code`, nunca solo por el estado HTTP ni por `error.message` — un código que esta operación aún no se ha visto lanzar sigue siendo más seguro para decidir que un texto pensado para una persona. | ErrorResponse |
