Factura afecta (33)
Campos, request por los 3 canales programáticos, response 202 y la tabla completa de estados SII, la referencia canónica de la familia de facturas.
El tipo_dte 33 es la Factura Electrónica afecta a IVA: el caso más común para SpAs,
empresas de servicios profesionales y comercio B2B. Esta es la página canónica de campos
de la familia de facturas: Factura exenta (34),
Nota de Crédito (61) y Nota de Débito (56)
documentan solo sus diferencias respecto de esta página.
Campos del request
POST /api/v1/dtes acepta este body para tipo 33:
| Campo | Tipo | Requerido | Descripción / constraint |
|---|---|---|---|
tipo_dte | number | sí | 33 para factura afecta |
rut_emisor | string | sí | RUT canónico BODY-DV sin puntos (76123456-0); el DV se valida módulo 11 |
receptor.rut | string | sí | Mismo formato canónico (11111111-1) |
receptor.razon_social | string | sí | Mínimo 1 carácter después de trim: espacios solos rechazan |
receptor.giro | string | sí (33/34) | Giro del receptor; obligatorio y no vacío para 33 y 34 |
receptor.direccion | string | sí (33/34) | Dirección del receptor; obligatoria y no vacía para 33 y 34 |
receptor.comuna | string | sí (33/34) | Comuna del receptor; obligatoria y no vacía para 33 y 34 |
fecha_emision | string | no | AAAA-MM-DD. Opcional: si se omite, se usa HOY en zona Chile. Ventana: desde el día 1 del mes en curso hasta hoy+7 días. Dentro del mes en curso la fecha es libre; el mes anterior está cerrado, también los primeros días del mes. Con fecha pasada el SII acepta el documento con reparos. |
items | array | sí | Entre 1 y 60 items |
items[].nombre | string | sí | Mínimo 1 carácter |
items[].cantidad | int | sí | Entero |
items[].precio_unitario | number | sí | Pesos CLP. Admite hasta 6 decimales (PrcItem del SII). El monto_item sí es entero |
items[].exento | boolean | sí | La 33 admite mezclar items afectos y exentos |
items[].monto_item | int | sí | Total de la línea en CLP |
items[].descuento_pct | number | no | Descuento de la línea en % (0–100). El SII lo emite como <DescuentoPct>; monto_item debe venir ya descontado (= cantidad*precio_unitario - round(cantidad*precio_unitario*descuento_pct/100)) |
forma_pago | 1 | 2 | 3 | sí (33/34) | Forma de pago: 1 Contado, 2 Crédito, 3 Sin costo. Obligatorio para 33 y 34. La UI pre-selecciona Crédito (2) |
references | array | no | Máximo 40. En la 33 son referencias comerciales, sin cod_ref: las correctivas pertenecen a NC y ND. Cada una lleva tipo_doc_ref con un código oficial de la tabla TpoDocRef del SII (o el alias orden_compra/contrato/hes). Ver el shape completo |
monto_neto | int | no | Si lo mandas, debe igualar la suma de items afectos |
monto_exento | int ≥ 0 | no | Si lo mandas, debe igualar la suma de items exentos |
iva | int | no | 19% sobre el neto |
monto_total | int | no | Debe igualar monto_neto + iva + monto_exento |
descuento_global | array | no | Descuentos/recargos globales del documento (<DscRcgGlobal>, hasta 20). Cada uno: tipo (descuento|recargo), es_porcentaje (true=%/false=$ CLP), valor, glosa (opcional), aplica_exento (opcional). Reducen/aumentan el neto afecto antes del IVA. No aplica a Factura de Compra 46 |
certificate_id | string (UUID) | no | Certificado digital específico; por defecto el activo de la organización |
sii_env | "cert" | "prod" | no | Default "cert" (maullin, sandbox del SII) |
Los montos son opcionales porque Notta los calcula desde los items. Si los mandas y no
cuadran, el endpoint responde 400 con código validation_failed y el detalle campo
por campo en issues[].
Request
Puedes emitir por los 2 canales programáticos (API, MCP) + el dashboard:
Este mismo POST es el que ejecuta una conexión MCP
La emisión está en el catálogo del servidor MCP, y es este mismo
POST /api/v1/dtes: un agente conectado lo llama con
execute({ operation: "emitDte", … }) si su conexión trae el permiso
dte:write, y ahí pasa por el gate de la empresa (techo, umbral y aprobación
humana sobre el monto que fijes). Con una API key el
gate no corre: la key la crea de forma deliberada alguien que ya podía emitir.
El X-Cert-Id es el id de tu certificado (paso 1 del quickstart o dashboard).
Response
El endpoint responde 202 Accepted: la emisión es asíncrona. El DTE queda queued,
y la transición a EPR ocurre tras firma + envío al SII (típicamente 2-15 segundos).
Para seguir el estado, lee links.events: GET /api/v1/dtes/{id}/events devuelve la
historia completa de transiciones en orden cronológico ascendente
({status, at, source, glosa} por cada una) con scope dte:read.
Es el endpoint canónico de seguimiento: trae
los estados transitorios que links.self ya no muestra (devuelve solo el último) y la
glosa del rechazo en el mismo request. POST /api/v1/dtes/{id}/refresh-status no es
el mecanismo de seguimiento: es la escotilla para un poll que se murió, y en bucle solo
abre sesiones contra el SII con tu certificado. El detalle de los dos está en
Referencia API de DTEs.
Descuentos
Notta soporta los dos descuentos del portal del SII:
- Por línea (
items[].descuento_pct): el porcentaje de descuento de esa línea.monto_itemdebe venir ya descontado: el%es informativo (<DescuentoPct>) y el SII validamonto_item = round(cantidad*precio_unitario) - descuento. - Global (
descuento_global): descuentos o recargos sobre el total del documento (<DscRcgGlobal>). Reducen (descuento) o aumentan (recargo) el neto afecto antes del IVA. Puedes combinar hasta 20 y usaraplica_exentopara que el ajuste vaya sobre la base exenta.
Notta recalcula monto_neto, iva y monto_total con los descuentos aplicados: no necesitas mandarlos.
En el ejemplo la línea aplica 15% (250000 → 212500) y el descuento global de 10% reduce el neto afecto (212500 → 191250) antes de calcular el IVA.
Estados SII
status y sii_status traen el mismo valor, y junto a ellos viene el bloque
estado con ese valor ya clasificado: terminal te dice cuándo dejar de esperar
y categoria / accion son enums cerrados para ramificar sin leer la prosa.
La tabla completa vive en Estados del DTE, con lo que significa cada código, cuál es terminal, la cadencia real del seguimiento y el algoritmo de espera recomendado. Es la única lista: duplicarla aquí es cómo un estado que ya nadie escribe sobrevive años en la documentación.
Lo que conviene saber al emitir una 33: espera hasta que estado.terminal sea
true (nunca hasta que sii_status valga EPR, porque un rechazo también es
final) y no te alarmes si ves -11. Ese código no es un estado del documento,
es la consulta de estado fallando mientras el SII todavía no registra el envío
recién subido, y es el camino normal de la mayoría de los documentos.
Idempotency
Todo POST exige el header Idempotency-Key (UUIDv7 recomendado); sin él, el endpoint
responde 400 con código idempotency_key_missing. Si la misma key llega dos veces,
retorna el resultado de la primera operación en lugar de duplicar el DTE.
El MCP genera keys frescas automáticamente.
Próximos pasos
- Nota de Crédito (61): corrige o anula una factura ya aceptada por el SII.
- Referencia API de DTEs: todos los endpoints de
/dtes(list, detail, PDF, XML y refresh-status). - Errores: el shape uniforme de error (
code,hint,next_action) y cómo manejarlo.
Última actualización