> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tupana.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Registrar estado de documento

> Registrar un nuevo estado cuando ocurre un evento relevante sobre el documento. Admite eventos del SII (ERM, ACD, RCD, RFT, RFP) y eventos internos de cobranza: **PAID** (marcar factura emitida como pagada) y **UNPAID** (marcar como no pagada). Para PAID y UNPAID solo el emisor del documento puede usarlos; aplican a facturas emitidas (tipo 33, 34, 39, 41). PAID genera un asiento contable de cierre de cuentas por cobrar (CxC); UNPAID revierte ese asiento si existe. También admite **ANNULLED** para anular una guía de despacho (DTE 52) emitida con folio, con `reason` obligatorio (Res. Ex. SII N°154: la guía que se reemplaza por otra queda registrada como anulada). Solo el emisor; la respuesta indica en `annulment.registry` dónde queda registrada la anulación: `delivery_note_book` (Libro de Guías, facturador de mercado) o `portal_follow_up` (facturador gratuito del SII: además hay que anotarla en "Seguimiento del documento" del portal mientras el SII no habilite el Registro de Guías). Errores 400 con `code`: `annulment_only_for_delivery_notes`, `annulment_only_for_issued_delivery_notes`, `annulment_reason_required`.

## Qué hace

* Crea un nuevo estado asociado al documento
* Agrega el evento al historial del documento
* No reemplaza ni elimina estados anteriores
* Permite registrar eventos manuales o automáticos

## Ejemplos de uso

* Marcar un documento como pagado
* Registrar un acuse de recibo
* Registrar un rechazo
* Asociar un evento proveniente del SII
* Registrar mérito ejecutivo o eventos de cobranza
* Anular una guía de despacho (DTE 52) con `event_code` `ANNULLED`

## Anular una guía de despacho (`ANNULLED`)

La [Resolución Exenta SII N°154](https://www.sii.cl/normativa_legislacion/resoluciones/2025/reso154.pdf) pide que, cuando cambia lo informado en una guía, se emita una nueva que la referencie y la original quede registrada como anulada. Se registra con este mismo endpoint, enviando el motivo:

```json theme={null}
{
  "event_code": "ANNULLED",
  "reason": "Reemplazada por guía folio 1051: cambió la cantidad de bultos"
}
```

Respuesta `200`:

```json theme={null}
{
  "success": true,
  "annulment": {
    "annulled": true,
    "already_annulled": false,
    "registry": "delivery_note_book",
    "registry_note": "La guía queda como anulada en el Libro de Guías de Despacho del período."
  }
}
```

* Sólo el emisor de la guía puede anularla (`403`).
* Sólo guías (DTE 52) emitidas con folio y siempre con `reason` (hasta 200 caracteres). Si no, `400` con `code`: `annulment_only_for_delivery_notes`, `annulment_only_for_issued_delivery_notes` o `annulment_reason_required`.
* `registry` dice dónde queda registrada la anulación mientras el SII no habilite el Registro de Guías: `delivery_note_book` (Libro de Guías, facturador de mercado) o `portal_follow_up` (facturador gratuito del SII: además hay que anotarla en "Seguimiento del documento" del portal, como explica `registry_note`).
* Anular una guía ya anulada responde `200` con `already_annulled: true`.


## OpenAPI

````yaml api-reference/openapi-v2.json POST /documents/{document_id}/states/
openapi: 3.0.0
info:
  title: Tupana API — v2
  description: >-
    API v2 de Tupana: facturación electrónica, cesiones, recaudación, consultas,
    boleta de honorarios y nómina. Los identificadores de recursos son public
    IDs opacos con prefijo (docu_, ment_, cred_, doce_, empl_…).
  version: 2.0.0
servers:
  - url: https://api.tupana.ai/v2
    description: Producción (v2)
security:
  - apiKeyAuth: []
paths:
  /documents/{document_id}/states/:
    post:
      tags:
        - Estados de Documentos
      summary: Registrar nuevo estado en un documento
      description: >-
        Registrar un nuevo estado cuando ocurre un evento relevante sobre el
        documento. Admite eventos del SII (ERM, ACD, RCD, RFT, RFP) y eventos
        internos de cobranza: **PAID** (marcar factura emitida como pagada) y
        **UNPAID** (marcar como no pagada). Para PAID y UNPAID solo el emisor
        del documento puede usarlos; aplican a facturas emitidas (tipo 33, 34,
        39, 41). PAID genera un asiento contable de cierre de cuentas por cobrar
        (CxC); UNPAID revierte ese asiento si existe. También admite
        **ANNULLED** para anular una guía de despacho (DTE 52) emitida con
        folio, con `reason` obligatorio (Res. Ex. SII N°154: la guía que se
        reemplaza por otra queda registrada como anulada). Solo el emisor; la
        respuesta indica en `annulment.registry` dónde queda registrada la
        anulación: `delivery_note_book` (Libro de Guías, facturador de mercado)
        o `portal_follow_up` (facturador gratuito del SII: además hay que
        anotarla en "Seguimiento del documento" del portal mientras el SII no
        habilite el Registro de Guías). Errores 400 con `code`:
        `annulment_only_for_delivery_notes`,
        `annulment_only_for_issued_delivery_notes`, `annulment_reason_required`.
      parameters:
        - name: document_id
          in: path
          description: ID único del documento (integer)
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DocumentStateRequest'
            examples:
              acuse_recibo:
                summary: Registrar acuse de recibo
                value:
                  event_code: ERM
              rechazo:
                summary: Registrar rechazo
                value:
                  event_code: RCD
                  rejection_reason: Error en el monto facturado
              aceptacion_contenido:
                summary: Aceptar contenido del documento
                value:
                  event_code: ACD
              marcar_como_pagado:
                summary: Marcar factura como pagada (PAID)
                description: >-
                  Solo emisor; factura emitida (33, 34, 39, 41). Genera asiento
                  de cierre CxC.
                value:
                  event_code: PAID
              marcar_como_no_pagado:
                summary: Marcar factura como no pagada (UNPAID)
                description: Solo emisor; revierte el asiento de cierre CxC si existe.
                value:
                  event_code: UNPAID
              anular_guia:
                summary: Anular guía de despacho (ANNULLED)
                description: >-
                  Solo emisor; guía (DTE 52) emitida con folio. Res. Ex. SII
                  N°154. La respuesta trae annulment.registry y
                  annulment.registry_note.
                value:
                  event_code: ANNULLED
                  reason: >-
                    Reemplazada por guía folio 1051: cambió la cantidad de
                    bultos
      responses:
        '200':
          description: Estado registrado exitosamente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentStateResponse'
              examples:
                respuesta_paid:
                  summary: Respuesta al marcar como pagado (PAID)
                  value:
                    success: true
                    event_registered: true
                    message: >-
                      Documento marcado como pagado. Se generó el asiento
                      contable de cierre de cuentas por cobrar.
                    document:
                      id: docu_9f2a7c1b8e4d0
                      folio: '42'
                      date_issued: '2025-01-15'
                      document_status:
                        paid_status: PAID
                respuesta_unpaid:
                  summary: Respuesta al marcar como no pagado (UNPAID)
                  value:
                    success: true
                    event_registered: true
                    message: >-
                      Documento marcado como no pagado. Se revirtió el asiento
                      de cierre de cuentas por cobrar.
                    document:
                      id: docu_9f2a7c1b8e4d0
                      folio: '42'
                      document_status:
                        paid_status: NOT_PAID
        '400':
          description: Parámetros inválidos o error al registrar el evento
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                parametros_faltantes:
                  value:
                    error: Se requiere el código del evento (event_code)
                evento_invalido:
                  value:
                    error: >-
                      Código de evento inválido. Debe ser uno de: ERM, ACD, RCD,
                      RFT, RFP, PAID, UNPAID
                error_sii:
                  value:
                    success: false
                    error: Error al registrar evento en el SII
                    error_code: SII_ERROR_CODE
        '401':
          description: No autenticado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Sin permisos para acceder a este documento
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Documento no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - apiKeyAuth: []
components:
  schemas:
    DocumentStateRequest:
      type: object
      required:
        - event_code
      properties:
        event_code:
          type: string
          enum:
            - ERM
            - ACD
            - RCD
            - RFT
            - RFP
            - PAID
            - UNPAID
            - ANNULLED
          description: >-
            Código del evento a registrar:

            - ERM: Acuse de Recibo de Mercaderías y Servicios

            - ACD: Acepta Contenido del Documento

            - RCD: Reclama Contenido del Documento

            - RFT: Reclamo por Falta Total

            - RFP: Reclamo por Falta Parcial

            - PAID: Marcar factura emitida como pagada (genera asiento cierre
            CxC; solo emisor; tipos 33, 34, 39, 41)

            - UNPAID: Marcar factura emitida como no pagada (revierte asiento
            cierre CxC; solo emisor)

            - ANNULLED: Anular una guía de despacho (52) emitida, con motivo en
            reason (Res. Ex. SII N°154; solo emisor)
          example: ERM
        rejection_reason:
          type: string
          description: >-
            Razón del rechazo (opcional, solo para eventos de rechazo: RCD, RFT,
            RFP)
          example: Error en el monto facturado
        reason:
          type: string
          maxLength: 200
          description: >-
            Motivo de la anulación. Obligatorio con ANNULLED (por ejemplo, el
            folio de la guía que la reemplaza). Se guarda con la guía anulada y
            se informa en el Libro de Guías.
          example: 'Reemplazada por guía folio 1051: cambió la cantidad de bultos'
    DocumentStateResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Indica si la operación fue exitosa
          example: true
        event_registered:
          type: boolean
          description: Indica si el evento fue registrado exitosamente
          example: true
        message:
          type: string
          description: Mensaje descriptivo del resultado
          example: >-
            Acuse de Recibo registrado. Este acuse rebajará el IVA del próximo
            mes.
        event_data:
          type: object
          description: Datos adicionales del evento registrado (proporcionados por el SII)
          additionalProperties: true
        document:
          $ref: '#/components/schemas/DocumentDetail'
        email_preview_data:
          type: object
          description: >-
            Datos para preview de email (solo para aprobaciones, rechazos o
            acuses de recibo)
          properties:
            should_open_modal:
              type: boolean
              example: true
            document_id:
              type: integer
              example: 12345
            action:
              type: string
              enum:
                - accept
                - reject
              example: accept
            subject:
              type: string
              example: Acuse de Recibo - Factura 123
            supplier_id:
              type: integer
              example: 67890
            supplier_name:
              type: string
              example: Proveedor Ejemplo S.A.
            supplier_rut:
              type: string
              example: 12345678-9
            document_folio:
              type: string
              example: '123'
            pdf_url:
              type: string
              format: uri
              nullable: true
              example: https://api.tupana.ai/v1/documents/12345/pdf
            rejection_reason:
              type: string
              nullable: true
              example: Error en el monto facturado
    Error:
      required:
        - error
        - message
      type: object
      properties:
        error:
          type: string
          description: Código de error
          example: VALIDATION_ERROR
          enum:
            - VALIDATION_ERROR
            - AUTHENTICATION_ERROR
            - AUTHORIZATION_ERROR
            - NOT_FOUND
            - SII_ERROR
            - INTERNAL_ERROR
        message:
          type: string
          description: Mensaje de error
    DocumentDetail:
      type: object
      properties:
        id:
          type: string
          description: ID único del documento
          example: docu_9f2a7c1b8e4d0
        folio:
          type: string
          nullable: true
          description: Número de folio del documento
        date_issued:
          type: string
          format: date
          description: Fecha de emisión del documento
        amount_with_iva:
          type: number
          format: float
          description: Monto total con IVA
        dte_type_code:
          type: string
          description: 'Código del tipo de DTE (ej: "33" para Factura Electrónica)'
        created_at:
          type: string
          format: date-time
          description: Fecha de creación del registro (ISO 8601)
        updated_at:
          type: string
          format: date-time
          description: Fecha de última actualización (ISO 8601)
        has_trace:
          type: boolean
          description: true si el documento tiene al menos una traza registrada del SII.
        json_param:
          type: object
          additionalProperties: true
          nullable: true
          description: >-
            Campos propios del cliente enviados en `json_param` al crear el
            documento. `null` si no se envió.
          example:
            external_order_id: PED-123
        additional_info:
          type: string
          nullable: true
          description: >-
            Texto enviado en `additional_info` al crear el documento. `null` si
            no se envió. Solo se imprime en el PDF si la empresa usa el PDF
            propio de Tu Pana o el facturador de mercado.
          example: 'Orden de compra N° 4500123 - Centro de costo: Operaciones'
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API Key para autenticación. Debe proporcionarse en el header
        Authorization con el formato: 'Api-Key YOUR-API-KEY' (incluye el prefijo
        'Api-Key ' seguido de tu API key)

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.