---
title: "Estados del DTE"
description: "Todos los estados de un DTE con su categoría, cuál es terminal y qué hacer con cada uno, más la cadencia real del seguimiento ante el SII."
url: https://notta.cl/docs/estados-dte
related:
  - https://notta.cl/docs/api/dtes
  - https://notta.cl/docs/webhooks
  - https://notta.cl/docs/agentes
  - https://notta.cl/docs/emit-factura-33
  - https://notta.cl/docs/errors
---

> Documentación de Notta en markdown. Índice completo: https://notta.cl/llms.txt. Corpus entero: https://notta.cl/llms-full.txt

# Estados del DTE

Emitir un DTE es asíncrono: `POST /dtes` responde `202` y el documento sigue
viajando. Esta página es la lista completa de los estados por los que pasa, qué
significa cada uno y cómo esperar el resultado sin escribir un bucle que no
termina nunca.

## El bloque `estado`

Toda respuesta que trae `sii_status` trae también `estado`, el mismo valor ya
clasificado. `sii_status` no cambia y sigue siendo el contrato: `estado` se
agrega. Está en `GET /dtes`, `GET /dtes/{id}`, el `202` de `POST /dtes` y en las
tres respuestas de `POST /dtes/{id}/refresh-status`.

```json
{
  "sii_status": "-11",
  "estado": {
    "code": "-11",
    "label": "procesando en el SII",
    "descripcion": "No es un estado del documento: es el código con el que FALLA la consulta de estado mientras el SII todavía no registra el envío recién subido.",
    "terminal": false,
    "poll_activo": true,
    "categoria": "en_proceso",
    "accion": "esperar"
  }
}
```

| Campo | Qué es |
|---|---|
| `code` | El mismo valor de `sii_status`. Es un **string**, no un enum cerrado, ver [El universo del SII es abierto](#el-universo-del-sii-es-abierto). |
| `label` | Glosa corta en español, para mostrar. |
| `descripcion` | Qué pasó y qué significa, en prosa. |
| `terminal` | `true` cuando el SII ya dio su veredicto sobre el documento. **Es la condición de corte de cualquier espera.** |
| `poll_activo` | `true` cuando hay un seguimiento nuestro consultándole el estado al SII en este momento. |
| `categoria` | Enum cerrado: `en_proceso` · `aceptado` · `rechazado` · `requiere_accion` · `archivistico`. |
| `accion` | Enum cerrado: `esperar` · `reintentar_consulta` · `reemitir` · `contactar_soporte` · `accion_en_sii` · `ninguna`. |

`categoria` y `accion` son estables igual que el `next_action` de los errores:
están diseñados para que ramifiques por código, sin leer `label` ni `descripcion`.

## Los estados

| Código | Qué significa | Terminal | Categoría | Acción |
|---|---|---|---|---|
| `queued` | El documento se creó en Notta y está en cola para firmarse y subirse. Todavía no salió. | no | `en_proceso` | `esperar` |
| `sending` | Notta está subiendo el documento al SII. Todavía no hay `track_id`. | no | `en_proceso` | `esperar` |
| `signed` | El XML ya está firmado con tu certificado y todavía no se sube. Etapa interna de Notta. | no | `en_proceso` | `esperar` |
| `SOK` | El SII validó el **esquema** del sobre. Etapa del envío, no un veredicto. | no | `en_proceso` | `esperar` |
| `CRT` | El SII validó la **carátula** del sobre (los datos de tu resolución). Etapa del envío. | no | `en_proceso` | `esperar` |
| `FOK` | El SII validó la **firma** electrónica del sobre. Etapa del envío. | no | `en_proceso` | `esperar` |
| `PDR` | El SII tiene el envío en proceso y todavía no lo resolvió. | no | `en_proceso` | `esperar` |
| `PRD` | El mismo estado que `PDR`: el instructivo del SII usa las dos grafías. | no | `en_proceso` | `esperar` |
| `-11` | La consulta de estado falla porque el SII todavía no registra el envío recién subido. Transitorio, y es el camino normal. | no | `en_proceso` | `esperar` |
| `EPR` | El SII procesó el envío y no reportó rechazos ni reparos: el documento quedó aceptado. | sí | `aceptado` | `ninguna` |
| `RPR` | Aceptado **con reparos**: el SII dejó observaciones. El documento es válido y exigible; no hay que reemitirlo. | sí | `aceptado` | `ninguna` |
| `accepted` | Documento importado del Respaldo del SII: el Servicio ya lo había aceptado cuando se emitió en tu sistema anterior. No hay envío que consultar. | sí | `archivistico` | `ninguna` |
| `RFR` | Rechazo por **firma**: el SII no pudo validar la firma electrónica. No es un problema de tus datos. El folio queda quemado. | sí | `rechazado` | `contactar_soporte` |
| `RCT` | Rechazo por **carátula**: los datos de la resolución que te autoriza a facturar no calzan con los del SII. Reemitir antes de corregirlo repite el rechazo y gasta otro folio. | sí | `rechazado` | `contactar_soporte` |
| `RSC` | Rechazo por **schema**: el XML no pasó la validación XSD del SII. Es un problema de cómo se genera el documento. El folio queda quemado. | sí | `rechazado` | `contactar_soporte` |
| `RCH` | El SII aceptó el envío y rechazó **este documento** por su contenido. Corrige el dato observado y emite uno nuevo con folio nuevo. | sí | `rechazado` | `reemitir` |
| `stuck` | El SII no dio veredicto dentro de la ventana del seguimiento y el proceso se agotó. **No es un rechazo**: el documento puede estar aceptado y no lo sabemos. | no | `requiere_accion` | `reintentar_consulta` |
| `sin_permiso_sii` | El SII respondió `106` al consultar: el RUT de tu certificado no está enrolado como usuario autorizado de la empresa. Es un fallo de la **consulta**, no un veredicto. Enrola al usuario en Mi SII → Usuarios autorizados. | no | `requiere_accion` | `accion_en_sii` |

`stuck` y `sin_permiso_sii` son `terminal: false` a propósito: en los dos casos el
SII no juzgó el documento. Por eso `refresh-status` sí los vuelve a consultar, y
por eso **no emitas un duplicado** mientras estén así: quemarías otro folio por
un documento que probablemente ya está aceptado.

### Dos estados históricos que el filtro sigue aceptando

`awaiting_sii` y `aceptado_con_reparos` se publicaron alguna vez y hoy ningún
proceso de Notta los escribe: producción no tiene ni un documento con ellos. Por
eso salieron de la tabla. Si escribiste una query con ellos leyendo nuestra
documentación anterior, `?sii_status=awaiting_sii` y
`?sii_status=aceptado_con_reparos` **siguen siendo valores válidos** en
`GET /dtes` y no devuelven `422`: no vas a recibir filas, pero tu integración no
se rompe. En código nuevo usa `RPR` en lugar de `aceptado_con_reparos`.

## Cómo esperar un DTE

Hay dos caminos, y las reglas de decisión son las mismas en los dos.

- **Push (`webhook`)**: registras una URL con `POST /api/v1/webhooks` y Notta te
  hace POST con cada transición, firmada y con reintentos. No esperas nada: tu
  handler recibe el `data` con los mismos `terminal`, `categoria` y `accion` de
  abajo. Es el camino si puedes exponer una URL https pública. Ver
  [Webhooks](/docs/webhooks).
- **Pull**: consultas tú. Es lo que sigue esta sección, y es además el camino de
  recuperación cuando una entrega de webhook no llega (`GET /dtes?polled_since=`).

Tres reglas, en orden:

1. **Corta por `estado.terminal`, nunca por `sii_status === "EPR"`.** Un rechazo
   también es final: un bucle que espera `EPR` sobre un `RCH` gira para siempre.
2. **Ramifica por `estado.categoria`**, no por el código. Son cinco casillas y
   cubren todo el universo, incluidos los códigos que todavía no conocemos.
3. **Un código que no reconoces no es terminal: sigue esperando.** Nunca lo
   trates como éxito.

```ts
async function esperarTerminal(id: string, token: string) {
  const limite = Date.now() + 15 * 60_000;
  while (Date.now() < limite) {
    const res = await fetch(`https://app.notta.cl/api/v1/dtes/${id}`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    const dte = await res.json();

    if (dte.estado?.terminal) {
      switch (dte.estado.categoria) {
        case "aceptado":
        case "archivistico":
          return dte; // listo: descarga el PDF en links.pdf
        case "rechazado":
          // El folio se quemó. `estado.accion` dice si reemitir o escalar.
          throw new Error(`${dte.sii_status}: ${dte.sii_glosa ?? dte.estado.descripcion}`);
      }
    }
    // No terminal (o un código desconocido): se sigue esperando.
    await new Promise((r) => setTimeout(r, 5_000));
  }
  throw new Error("se agotó la espera; el documento sigue en vuelo");
}
```

El cliente de TypeScript de Notta trae este mismo bucle listo, con backoff y con
el corte por `estado.terminal`. **Todavía no está publicado en npm**, así que hoy
el camino es el `fetch` de arriba; cuando se publique, la llamada equivalente es:

```ts
const res = await client.waitForTerminal(id, { timeout: 15 * 60_000 });
if (res.ok && res.data.estado.categoria === "rechazado") {
  // el folio se quemó: hay que emitir uno nuevo corregido
}
```

> **No leas `sii_status` como si fuera un enum cerrado:**
El SII no publica una lista cerrada de códigos, y Notta guarda verbatim lo que
responde. Un `switch (sii_status)` con un `default` que asume éxito es un bug
esperando su código nuevo; un `switch (estado.categoria)` no, porque las
categorías sí son nuestras y sí son cerradas.

## Cuánto tarda: la cadencia del seguimiento

No hace falta que fuerces nada. Cada DTE emitido publica un seguimiento durable
que lo lleva a su estado final por su cuenta, con esta cadencia de consultas al
SII:

| Tramo | Consultas al SII |
|---|---|
| Primeros 5 minutos | 11: la inmediata, más una cada 30 segundos |
| Del minuto 5 al 10 | 5: una por minuto |
| Del minuto 15 a las 15 h 45 min | 6: a los 5 min, 30 min, 1 h, 2 h, 4 h y 8 h de la anterior |
| Desde las 15 h 45 min | 7: una cada 24 horas |

Son **29 consultas** repartidas en una ventana de **7 d 15 h 45 min**. Ese es el
número exacto, no "7 días": si se agota sin veredicto, el documento queda en
`stuck` y ahí sí necesita que alguien intervenga.

En la práctica el grueso se resuelve en los primeros minutos. La estadística de
producción explica por qué `-11` es tan común: **221 de los 283 documentos** que
llegaron a un estado terminal pasaron por él, con una permanencia promedio de
**213 segundos** y un máximo de **3 h 46 min**. Ver un `-11` no significa que algo
salió mal; significa que el SII todavía no registró el envío.

Para enterarte de las transiciones sin preguntar, registra un webhook: cada una
de esas consultas que cambia el estado dispara una entrega a tu URL. Si prefieres
preguntar tú, `GET /dtes/{id}/events` es el endpoint canónico de pull: devuelve
la historia completa en orden cronológico, con la glosa del SII, incluidos los
estados transitorios que `GET /dtes/{id}` ya no muestra. Para muchos documentos a
la vez, `GET /dtes` acepta `sii_status` y `polled_since`, ver
[Referencia API de DTEs](/docs/api/dtes).

## `refresh-status` es una escotilla, no el seguimiento

`POST /dtes/{id}/refresh-status` existe para revivir un seguimiento que se murió.
Tiene tres respuestas `2xx` y **dos de las tres no hacen nada**:

| Respuesta | HTTP | Qué significa |
|---|---|---|
| `refresh_enqueued` | `202` | La única que actúa: se encoló una consulta nueva al SII. |
| `already_terminal` | `200` | El SII ya juzgó el documento. **Puede ser un rechazo**: trae `sii_glosa` y `estado`. Léelos antes de darlo por bueno. |
| `poll_in_progress` | `200` | El seguimiento sigue vivo. Trae `retry_after` en **segundos**: cuánto falta para que esta llamada deje de ser un no-op. |

El gate que decide entre `poll_in_progress` y `refresh_enqueued` es el reloj: si
`sii_last_polled` se movió hace menos de **25 h**, se asume que el seguimiento
está vivo y la llamada no encola nada. El umbral no es arbitrario: supera la
espera legítima más larga de la cadencia (24 h) con una hora de margen. `stuck` y
`sin_permiso_sii` se saltan ese gate: ahí ya no hay nadie consultando, y la
escotilla es justo para eso.

```bash
curl -X POST https://app.notta.cl/api/v1/dtes/01977f2a-1b50-7000-8000-000000000001/refresh-status \
  -H "Authorization: Bearer ntt_cert_..." \
  -H "X-Cert-Id: 01977f00-0000-7000-8000-000000000abc" \
  -H "Idempotency-Key: $(uuidgen)"
```

```json
{
  "id": "01977f2a-1b50-7000-8000-000000000001",
  "status": "already_terminal",
  "sii_status": "RCH",
  "sii_glosa": "Documento rechazado por el SII",
  "estado": {
    "code": "RCH",
    "label": "documento rechazado",
    "terminal": true,
    "poll_activo": false,
    "categoria": "rechazado",
    "accion": "reemitir"
  }
}
```

Llamarlo en bucle no acelera nada y abre una sesión más contra el SII con tu
certificado por cada llamada.

## El universo del SII es abierto

El instructivo del SII cierra su tabla de códigos de estado con una fila
literal: **«Otros (no enumerados)»**. El seguimiento de Notta guarda verbatim lo
que responde el Servicio, así que en producción ya hay códigos fuera de la tabla
de arriba: `106` y `107` viven hoy en el historial de estados de documentos
reales.

Por eso el contrato está partido en dos mitades con reglas distintas:

- **`estado.code` es un string**, no un enum. Declararlo cerrado obligaría a
  rechazar valores que la propia base de datos contiene.
- **`estado.categoria` y `estado.accion` sí son cerrados**, porque son vocabulario
  de Notta. Un código que no conocemos igual cae en una casilla accionable:
  `terminal: false`, `categoria: "en_proceso"` y `accion: "contactar_soporte"`.
  Nunca `accion: "ninguna"`, que se leería como éxito.

Si te topas con un `code` que no está en esta página, trátalo como no terminal y
escríbenos con el `track_id` del documento.

## Próximos pasos

- **[Referencia API de DTEs](/docs/api/dtes)**: `GET /dtes/{id}/events`, los filtros del listado y el contrato completo de `refresh-status`.
- [Webhooks](/docs/webhooks): el mismo bloque `estado`, pero por push, con firma y reintentos.
- [Notta para agentes](/docs/agentes): el contrato de errores y el de estados, juntos, con el prompt de arranque.
- [Emitir Factura 33](/docs/emit-factura-33): la guía del caso más común, de punta a punta.
- [Errores](/docs/errors): el catálogo de `code` y `next_action` para el otro lado del contrato.
