> ## 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.

## 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


## OpenAPI

````yaml POST /documents/{document_id}/states
openapi: 3.0.0
info:
  title: Tupana API
  description: API para integración con el sistema Tupana - Facturación Electrónica
  version: 1.0.0
servers:
  - url: https://api.tupana.ai/v1
    description: Servidor de producción
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.
      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
      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: 12345
                      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: 12345
                      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
          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)
          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
    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: integer
          description: ID único del documento
        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.
        latest_trace_info:
          $ref: '#/components/schemas/LatestTraceInfo'
    LatestTraceInfo:
      type: object
      description: >-
        Resumen liviano de la última traza del documento. Siempre se incluye en
        las respuestas de listado y detalle (es `null` cuando el documento no
        tiene trazas).
      nullable: true
      properties:
        has_acknowledgments:
          type: boolean
          description: El documento tiene un acuse de recibo (eventos ACD o ERM).
        has_claims:
          type: boolean
          description: El documento tiene al menos un reclamo (RCD, RFP o RFT).
        is_more_than_eight_days:
          type: boolean
          description: >-
            Han pasado más de 8 días desde la recepción (relevante para mérito
            ejecutivo).
        is_rejected:
          type: boolean
          description: >-
            Calculado: el documento fue rechazado (existe un evento RCD, RFP o
            RFT).
        date_reception:
          type: string
          format: date-time
          description: Fecha y hora en que el SII registró la recepción del documento.
          nullable: true
        events_count:
          type: integer
          description: >-
            Cantidad total de eventos en esta traza. Útil para decidir si vale
            la pena solicitar `?include_trace_events=true` en el listado.
  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)

````