{
  "openapi": "3.1.0",
  "info": {
    "title": "sudte API",
    "version": "1.0.0-draft",
    "summary": "Facturación electrónica (DTE) para El Salvador",
    "description": "API de sudte para emitir, consultar e invalidar Documentos Tributarios Electrónicos ante el\nMinisterio de Hacienda de El Salvador.\n\n- Autenticación: `Authorization: Bearer sk_test_…` (ambiente de pruebas MH `00`) o `sk_live_…` (producción `01`).\n- Todos los POST requieren `Idempotency-Key`. Misma clave con otro cuerpo responde 409.\n  Excepción: los endpoints de sesión del panel (`/auth/*`) no lo requieren.\n- Panel (app.sudte.com): cookie `sudte_session` + `X-CSRF-Token` (valor de `Session.csrf_token`) en métodos no seguros.\n- Montos como string decimal (`\"113.00\"`). Fechas ISO 8601, zona America/El_Salvador.\n- Errores en `application/problem+json` (RFC 9457), mensajes en español.\n\nEste archivo es el contrato: se edita primero y de él salen docs, SDKs, panel y conector Odoo.\n",
    "contact": {
      "name": "sudte",
      "url": "https://sudte.com",
      "email": "soporte@sudte.com"
    }
  },
  "servers": [
    {
      "url": "https://api.sudte.com/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    },
    {
      "session": []
    }
  ],
  "tags": [
    {
      "name": "Documentos",
      "description": "Emisión y ciclo de vida de DTE"
    },
    {
      "name": "Emisores",
      "description": "Contribuyentes que emiten DTE"
    },
    {
      "name": "Webhooks",
      "description": "Notificaciones de eventos"
    },
    {
      "name": "Catálogos",
      "description": "Catálogos oficiales del MH"
    },
    {
      "name": "Reportes fiscales",
      "description": "Libros de IVA y anexos MH generados por sudte (ADR 0002). Ingesta de compras, retenciones recibidas y ventas externas"
    },
    {
      "name": "Cuenta",
      "description": "Panel de clientes (sesión), API keys, uso y facturación"
    }
  ],
  "paths": {
    "/documents": {
      "post": {
        "tags": [
          "Documentos"
        ],
        "operationId": "createDocument",
        "summary": "Emitir un DTE",
        "description": "sudte calcula, arma el JSON oficial, valida contra el esquema del MH, firma, transmite y devuelve el sello.\n`mode=sync` (por defecto) espera hasta 20 s; si MH no responde a tiempo devuelve 202 y notifica por webhook.\n`dry_run=true` valida y calcula sin firmar ni transmitir (sin costo).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "mode",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "sync",
                "async"
              ],
              "default": "sync"
            }
          },
          {
            "name": "dry_run",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentCreate"
              },
              "examples": {
                "factura": {
                  "summary": "Factura (01) a consumidor final",
                  "value": {
                    "emitter_id": "emi_01HZY",
                    "type": "01",
                    "establishment": "M001",
                    "point_of_sale": "P001",
                    "external_id": "odoo-account.move-1542",
                    "receiver": {
                      "name": "Cliente final",
                      "email": "cliente@example.com"
                    },
                    "items": [
                      {
                        "description": "Servicio de soporte",
                        "quantity": "1",
                        "unit_price": "113.00",
                        "unit_code": "59",
                        "tax": "gravada"
                      }
                    ],
                    "payment": {
                      "condition": "1",
                      "methods": [
                        {
                          "code": "01",
                          "amount": "113.00"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado de dry_run (sin firmar ni transmitir)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "201": {
            "description": "Documento procesado por MH",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "Aceptado; en proceso o en contingencia. Se notificará por webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      },
      "get": {
        "tags": [
          "Documentos"
        ],
        "operationId": "listDocuments",
        "summary": "Listar documentos",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "name": "emitter_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/DteType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/DocumentStatus"
            }
          },
          {
            "name": "external_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "issued_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "issued_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Environment"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Búsqueda libre: número de control, código de generación, sello, nombre o documento del receptor",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de documentos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentList"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Documentos"
        ],
        "operationId": "getDocument",
        "summary": "Obtener un documento (incluye estado actualizado)",
        "responses": {
          "200": {
            "description": "Documento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/json": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Documentos"
        ],
        "operationId": "getDocumentJson",
        "summary": "JSON oficial firmado con sello (el que se entrega al receptor)",
        "responses": {
          "200": {
            "description": "JSON del DTE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/pdf": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Documentos"
        ],
        "operationId": "getDocumentPdf",
        "summary": "Representación gráfica en PDF con QR de consulta pública",
        "responses": {
          "200": {
            "description": "PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/send": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Documentos"
        ],
        "operationId": "sendDocument",
        "summary": "Enviar (o reenviar) JSON y PDF por correo al receptor",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Envío encolado"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/retry": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Documentos"
        ],
        "operationId": "retryDocument",
        "summary": "Reintentar la transmisión (o corregir y reenviar un rechazado)",
        "description": "- `signed`, `sending`, `error` o `contingency`: consulta primero el estado en MH y, si no lo tiene, retransmite\n  el MISMO JSON firmado (nunca se vuelve a firmar con otro contenido).\n- `rejected`: si se envía un cuerpo `DocumentCreate` corregido, se rearma conservando `generation_code` y\n  `control_number` (Normativa §10: corregir y retransmitir dentro de 24 h con el mismo código de generación).\n  Sin cuerpo, retransmite el mismo JSON.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado del reintento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "202": {
            "description": "MH no respondió a tiempo; se notificará por webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/void": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Documentos"
        ],
        "operationId": "voidDocument",
        "summary": "Invalidar (evento de invalidación ante MH)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason_type",
                  "reason",
                  "responsible",
                  "requester"
                ],
                "properties": {
                  "reason_type": {
                    "type": "string",
                    "enum": [
                      "1",
                      "2",
                      "3"
                    ],
                    "description": "CAT-024 Motivo del evento"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 250
                  },
                  "replacement_document_id": {
                    "type": "string",
                    "description": "Requerido salvo rescisión total (tipo 2)"
                  },
                  "responsible": {
                    "$ref": "#/components/schemas/Person"
                  },
                  "requester": {
                    "$ref": "#/components/schemas/Person"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Invalidación procesada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Document"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters": {
      "get": {
        "tags": [
          "Emisores"
        ],
        "operationId": "listEmitters",
        "summary": "Listar emisores de la cuenta",
        "responses": {
          "200": {
            "description": "Emisores",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Emitter"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Emisores"
        ],
        "operationId": "createEmitter",
        "summary": "Registrar un emisor",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmitterInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Emisor creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Emitter"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Emisores"
        ],
        "operationId": "getEmitter",
        "summary": "Obtener emisor",
        "responses": {
          "200": {
            "description": "Emisor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Emitter"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Emisores"
        ],
        "operationId": "updateEmitter",
        "summary": "Actualizar emisor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmitterInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Emisor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Emitter"
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/credentials": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "put": {
        "tags": [
          "Emisores"
        ],
        "operationId": "setEmitterCredentials",
        "summary": "Cargar certificado del MH y credenciales de la API del MH por ambiente",
        "description": "Se guardan cifrados (KMS). Nunca se devuelven. Valida la clave contra el certificado y hace login de prueba en MH.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "environment"
                ],
                "properties": {
                  "environment": {
                    "$ref": "#/components/schemas/Environment"
                  },
                  "certificate": {
                    "type": "string",
                    "format": "binary",
                    "description": "Archivo .crt emitido por el MH"
                  },
                  "private_key_password": {
                    "type": "string",
                    "format": "password"
                  },
                  "mh_user": {
                    "type": "string",
                    "description": "NIT del usuario de la API del MH"
                  },
                  "mh_password": {
                    "type": "string",
                    "format": "password"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Credenciales válidas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialStatus"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}/credentials/test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "post": {
        "tags": [
          "Emisores"
        ],
        "operationId": "testEmitterCredentials",
        "summary": "Probar conexión con el MH con las credenciales guardadas (login de prueba y validación de certificado)",
        "description": "No requiere volver a subir el certificado. Actualiza `checked_at`, `mh_login_ok` y `message`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "environment"
                ],
                "properties": {
                  "environment": {
                    "$ref": "#/components/schemas/Environment"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado de la prueba (ver `mh_login_ok` y `message`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CredentialStatus"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}/establishments": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Emisores"
        ],
        "operationId": "listEstablishments",
        "summary": "Establecimientos y puntos de venta",
        "responses": {
          "200": {
            "description": "Lista",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Establishment"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Emisores"
        ],
        "operationId": "createEstablishment",
        "summary": "Crear establecimiento",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Establishment"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Establishment"
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/establishments/{establishment_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "name": "establishment_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "tags": [
          "Emisores"
        ],
        "operationId": "updateEstablishment",
        "summary": "Actualizar establecimiento y sus puntos de venta",
        "description": "`points_of_sale` reemplaza la lista completa. Un punto de venta con documentos emitidos no se borra: se marca `active: false`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Establishment"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Establishment"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/webhook-endpoints": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookEndpoints",
        "summary": "Listar endpoints de webhook",
        "responses": {
          "200": {
            "description": "Lista",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhookEndpoint",
        "summary": "Registrar endpoint (devuelve el secreto de firma una sola vez)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EventType"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteWebhookEndpoint",
        "summary": "Eliminar endpoint",
        "responses": {
          "204": {
            "description": "Eliminado"
          }
        }
      }
    },
    "/webhook-endpoints/{id}/test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "testWebhookEndpoint",
        "summary": "Enviar un evento de prueba (`document.processed` ficticio, ambiente 00) al endpoint",
        "responses": {
          "202": {
            "description": "Evento de prueba encolado"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/catalogs/{code}": {
      "get": {
        "tags": [
          "Catálogos"
        ],
        "operationId": "getCatalog",
        "summary": "Catálogo oficial del MH (CAT-001..CAT-033)",
        "security": [],
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^CAT-\\d{3}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Catálogo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Catalog"
                }
              }
            }
          }
        }
      }
    },
    "/plans": {
      "get": {
        "tags": [
          "Cuenta"
        ],
        "operationId": "listPlans",
        "summary": "Planes públicos vigentes (precios sin IVA, USD)",
        "security": [],
        "responses": {
          "200": {
            "description": "Planes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Plan"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/fiscal/{resource}/batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/FiscalResource"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "ingestFiscalBatch",
        "summary": "Upsert por lote (máx. 500) de compras, retenciones recibidas o ventas externas",
        "description": "Idempotente por `external_id` + `version`. Respuesta con resultado por ítem. Periodo cerrado = error por ítem.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "items"
                ],
                "properties": {
                  "items": {
                    "type": "array",
                    "maxItems": 500,
                    "items": {
                      "$ref": "#/components/schemas/FiscalRecord"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado por ítem",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalBatchResult"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}/fiscal/{resource}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/FiscalResource"
        }
      ],
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "listFiscalRecords",
        "summary": "Listar registros ingeridos de un periodo",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}$"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          }
        ],
        "responses": {
          "200": {
            "description": "Registros",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FiscalRecord"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/fiscal/{resource}/{external_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/FiscalResource"
        },
        {
          "name": "external_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "put": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "upsertFiscalRecord",
        "summary": "Crear o actualizar un registro (idempotente por versión)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FiscalRecord"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Guardado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalRecord"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      },
      "delete": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "deleteFiscalRecord",
        "summary": "Eliminar (borrado lógico; falla si el periodo está cerrado)",
        "responses": {
          "204": {
            "description": "Eliminado"
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/documents/{id}/fiscal": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "patch": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "updateDocumentFiscalTags",
        "summary": "Etiquetas fiscales de un DTE emitido (códigos de renta, zona franca, excluir de libros…)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FiscalTags"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalTags"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/fiscal/report-types": {
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "listFiscalReportTypes",
        "summary": "Catálogo de reportes con JSON Schema de parámetros y formatos disponibles",
        "responses": {
          "200": {
            "description": "Catálogo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FiscalReportType"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/fiscal/reports": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "post": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "createFiscalReport",
        "summary": "Generar reporte de un periodo",
        "description": "202 en cola; 200 si ya existe un resultado vigente (mismo input_hash) o el periodo está cerrado (snapshot).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "period"
                ],
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "period": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}$"
                  },
                  "params": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado existente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalReport"
                }
              }
            }
          },
          "202": {
            "description": "En cola",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalReport"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/fiscal/reports/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "getFiscalReport",
        "summary": "Estado, totales, advertencias y drift",
        "responses": {
          "200": {
            "description": "Reporte",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalReport"
                }
              }
            }
          }
        }
      }
    },
    "/fiscal/reports/{id}/rows": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "getFiscalReportRows",
        "summary": "Filas paginadas con columnas definidas por el servidor (el cliente solo pinta)",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Filas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalReportRows"
                }
              }
            }
          }
        }
      }
    },
    "/fiscal/reports/{id}/files/{format}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "name": "format",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "enum": [
              "csv",
              "xlsx",
              "pdf",
              "zip"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "downloadFiscalReport",
        "summary": "Descargar (302 a URL prefirmada de corta duración)",
        "responses": {
          "302": {
            "description": "Redirección al archivo",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}/fiscal/periods": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        }
      ],
      "get": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "listFiscalPeriods",
        "summary": "Periodos y su estado (abierto, cerrado, versión, drift)",
        "responses": {
          "200": {
            "description": "Periodos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FiscalPeriod"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emitters/{id}/fiscal/periods/{period}/close": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/Period"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "closeFiscalPeriod",
        "summary": "Cerrar periodo (snapshots inmutables con hash de todos los reportes)",
        "responses": {
          "202": {
            "description": "Cierre en proceso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalPeriod"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/emitters/{id}/fiscal/periods/{period}/reopen": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Id"
        },
        {
          "$ref": "#/components/parameters/Period"
        },
        {
          "$ref": "#/components/parameters/IdempotencyKey"
        }
      ],
      "post": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "reopenFiscalPeriod",
        "summary": "Reabrir periodo con motivo (crea versión nueva; requiere scope fiscal:close)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reabierto",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FiscalPeriod"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/fiscal/embed-sessions": {
      "post": {
        "tags": [
          "Reportes fiscales"
        ],
        "operationId": "createFiscalEmbedSession",
        "summary": "URL firmada de un solo uso (≤300 s, solo lectura) para abrir la vista del panel desde Odoo",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "emitter_id"
                ],
                "properties": {
                  "emitter_id": {
                    "type": "string"
                  },
                  "report_type": {
                    "type": "string"
                  },
                  "period": {
                    "type": "string"
                  },
                  "ttl": {
                    "type": "integer",
                    "maximum": 300,
                    "default": 300
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sesión",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/account/usage": {
      "get": {
        "tags": [
          "Cuenta"
        ],
        "operationId": "getUsage",
        "summary": "Uso del periodo (documentos procesados por emisor y tipo)",
        "security": [
          {
            "session": []
          },
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Uso",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "sk_test_… o sk_live_…"
      },
      "session": {
        "type": "apiKey",
        "in": "cookie",
        "name": "sudte_session",
        "description": "Sesión del panel app.sudte.com"
      }
    },
    "parameters": {
      "Id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "maxLength": 255
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "StartingAfter": {
        "name": "starting_after",
        "in": "query",
        "schema": {
          "type": "string"
        }
      },
      "FiscalResource": {
        "name": "resource",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "enum": [
            "purchases",
            "withholdings-received",
            "external-sales"
          ]
        }
      },
      "Period": {
        "name": "period",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}$"
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "Error (RFC 9457)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "Money": {
        "type": "string",
        "pattern": "^-?\\d+(\\.\\d{1,8})?$",
        "examples": [
          "113.00"
        ]
      },
      "Environment": {
        "type": "string",
        "enum": [
          "00",
          "01"
        ],
        "description": "00 pruebas, 01 producción (CAT-001)"
      },
      "DteType": {
        "type": "string",
        "enum": [
          "01",
          "03",
          "04",
          "05",
          "06",
          "07",
          "08",
          "09",
          "11",
          "14",
          "15"
        ],
        "description": "CAT-002. Semana 1 implementa 01, 03, 05 y 06."
      },
      "DocumentStatus": {
        "type": "string",
        "enum": [
          "draft",
          "validated",
          "signed",
          "sending",
          "processed",
          "rejected",
          "contingency",
          "voided",
          "error"
        ]
      },
      "EventType": {
        "type": "string",
        "enum": [
          "document.processed",
          "document.rejected",
          "document.contingency",
          "document.voided",
          "document.delivered",
          "fiscal.report.ready",
          "fiscal.report.failed",
          "fiscal.period.closed",
          "fiscal.period.drift_detected"
        ]
      },
      "Person": {
        "type": "object",
        "required": [
          "name",
          "document_type",
          "document_number"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "document_type": {
            "type": "string",
            "description": "CAT-022"
          },
          "document_number": {
            "type": "string"
          }
        }
      },
      "Address": {
        "type": "object",
        "properties": {
          "department": {
            "type": "string",
            "description": "CAT-012"
          },
          "municipality": {
            "type": "string",
            "description": "CAT-013"
          },
          "district": {
            "type": "string",
            "description": "CAT-008"
          },
          "line": {
            "type": "string"
          }
        }
      },
      "Receiver": {
        "type": "object",
        "description": "Requerido según tipo. En FE puede omitirse si el total es menor al umbral del Aviso DGII ($25,000).",
        "properties": {
          "name": {
            "type": "string"
          },
          "document_type": {
            "type": "string",
            "description": "CAT-022 (36 NIT, 13 DUI, 37 otro, 03 pasaporte, 02 carnet residente)"
          },
          "document_number": {
            "type": "string"
          },
          "nrc": {
            "type": "string"
          },
          "economic_activity": {
            "type": "string",
            "description": "CAT-019"
          },
          "trade_name": {
            "type": "string"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "description": "CAT-020 (exportación)"
          }
        }
      },
      "Item": {
        "type": "object",
        "required": [
          "description",
          "quantity",
          "unit_price",
          "tax"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "1",
              "2",
              "3",
              "4"
            ],
            "default": "1",
            "description": "CAT-011"
          },
          "code": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          },
          "quantity": {
            "$ref": "#/components/schemas/Money"
          },
          "unit_code": {
            "type": "string",
            "default": "59",
            "description": "CAT-014"
          },
          "unit_price": {
            "$ref": "#/components/schemas/Money",
            "description": "FE: con IVA. CCF/NC/ND: sin IVA."
          },
          "discount": {
            "$ref": "#/components/schemas/Money"
          },
          "tax": {
            "type": "string",
            "enum": [
              "gravada",
              "exenta",
              "no_sujeta"
            ]
          },
          "taxes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tributos CAT-015 adicionales"
          },
          "related_document": {
            "type": "string",
            "description": "codigoGeneracion relacionado (NC/ND)"
          }
        }
      },
      "DocumentCreate": {
        "type": "object",
        "required": [
          "emitter_id",
          "type",
          "establishment",
          "point_of_sale",
          "items"
        ],
        "properties": {
          "emitter_id": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/DteType"
          },
          "establishment": {
            "type": "string",
            "description": "Código MH del establecimiento (4)"
          },
          "point_of_sale": {
            "type": "string",
            "description": "Código MH del punto de venta (4)"
          },
          "external_id": {
            "type": "string",
            "description": "Id en el sistema del cliente (ej. Odoo)"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time",
            "description": "Por defecto ahora; holgura máxima 30 min"
          },
          "receiver": {
            "$ref": "#/components/schemas/Receiver"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 2000,
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "global_discount": {
            "type": "object",
            "properties": {
              "gravada": {
                "$ref": "#/components/schemas/Money"
              },
              "exenta": {
                "$ref": "#/components/schemas/Money"
              },
              "no_sujeta": {
                "$ref": "#/components/schemas/Money"
              }
            }
          },
          "withholding": {
            "type": "object",
            "properties": {
              "iva_1": {
                "type": "boolean"
              },
              "renta": {
                "$ref": "#/components/schemas/Money"
              }
            }
          },
          "perception": {
            "type": "boolean",
            "description": "Percepción IVA 1%"
          },
          "payment": {
            "type": "object",
            "properties": {
              "condition": {
                "type": "string",
                "enum": [
                  "1",
                  "2",
                  "3"
                ],
                "description": "CAT-016"
              },
              "methods": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "CAT-017"
                    },
                    "amount": {
                      "$ref": "#/components/schemas/Money"
                    },
                    "reference": {
                      "type": "string"
                    },
                    "term": {
                      "type": "string",
                      "description": "CAT-018"
                    },
                    "period": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "related_documents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "$ref": "#/components/schemas/DteType"
                },
                "generation_code": {
                  "type": "string"
                },
                "issued_on": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          },
          "notes": {
            "type": "string"
          },
          "appendix": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          },
          "raw": {
            "type": "object",
            "description": "Avanzado. JSON MH ya armado (sin firma); sudte solo valida, firma y transmite."
          },
          "send_email": {
            "type": "boolean",
            "default": true
          },
          "environment": {
            "$ref": "#/components/schemas/Environment",
            "description": "Solo con sesión del panel (por defecto 00). Con API key el ambiente lo determina la key y este campo se ignora"
          }
        }
      },
      "Document": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "document"
          },
          "emitter_id": {
            "type": "string"
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "type": {
            "$ref": "#/components/schemas/DteType"
          },
          "status": {
            "$ref": "#/components/schemas/DocumentStatus"
          },
          "external_id": {
            "type": "string"
          },
          "generation_code": {
            "type": "string",
            "description": "codigoGeneracion"
          },
          "control_number": {
            "type": "string",
            "description": "numeroControl"
          },
          "reception_stamp": {
            "type": "string",
            "description": "selloRecibido"
          },
          "processed_at": {
            "type": "string",
            "format": "date-time"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "totals": {
            "type": "object",
            "properties": {
              "subtotal": {
                "$ref": "#/components/schemas/Money"
              },
              "iva": {
                "$ref": "#/components/schemas/Money"
              },
              "total": {
                "$ref": "#/components/schemas/Money"
              },
              "total_in_words": {
                "type": "string"
              }
            }
          },
          "mh_response": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "observations": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "public_url": {
            "type": "string",
            "format": "uri",
            "description": "Consulta pública MH (QR)"
          },
          "pdf_url": {
            "type": "string",
            "format": "uri"
          },
          "json_url": {
            "type": "string",
            "format": "uri"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "emitter_name": {
            "type": "string"
          },
          "establishment": {
            "type": "string",
            "description": "Código MH del establecimiento"
          },
          "point_of_sale": {
            "type": "string",
            "description": "Código MH del punto de venta"
          },
          "receiver": {
            "type": "object",
            "description": "Resumen del receptor para listados",
            "properties": {
              "name": {
                "type": "string"
              },
              "document_type": {
                "type": "string"
              },
              "document_number": {
                "type": "string"
              },
              "nrc": {
                "type": "string"
              },
              "email": {
                "type": "string"
              }
            }
          },
          "related_documents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "$ref": "#/components/schemas/DteType"
                },
                "generation_code": {
                  "type": "string"
                }
              }
            }
          },
          "voided_at": {
            "type": "string",
            "format": "date-time"
          },
          "void": {
            "type": "object",
            "description": "Datos de la invalidación si `status=voided`",
            "properties": {
              "reason_type": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              },
              "replacement_document_id": {
                "type": "string"
              },
              "reception_stamp": {
                "type": "string"
              }
            }
          },
          "warnings": {
            "type": "array",
            "description": "Advertencias no bloqueantes (p. ej. retención no aplicada por monto menor a $100)",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "events": {
            "type": "array",
            "description": "Historial (creado, firmado, transmitido, reintento, sellado, rechazado, correo enviado, invalidado)",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "DocumentList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          },
          "has_more": {
            "type": "boolean"
          }
        }
      },
      "EmitterInput": {
        "type": "object",
        "required": [
          "nit",
          "nrc",
          "name",
          "economic_activity",
          "address",
          "email"
        ],
        "properties": {
          "nit": {
            "type": "string"
          },
          "nrc": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "trade_name": {
            "type": "string"
          },
          "economic_activity": {
            "type": "string",
            "description": "CAT-019"
          },
          "establishment_type": {
            "type": "string",
            "description": "CAT-009"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "numbering": {
            "type": "string",
            "enum": [
              "centralized",
              "per_establishment"
            ],
            "default": "per_establishment",
            "description": "Normativa §7.1.2"
          },
          "logo_url": {
            "type": "string",
            "format": "uri"
          },
          "is_large_taxpayer": {
            "type": "boolean",
            "default": false,
            "description": "Gran contribuyente (agente de retención/percepción). Habilita `perception` en CCF"
          }
        }
      },
      "Emitter": {
        "allOf": [
          {
            "$ref": "#/components/schemas/EmitterInput"
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "credentials": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CredentialStatus"
                }
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "CredentialStatus": {
        "type": "object",
        "properties": {
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "certificate_loaded": {
            "type": "boolean"
          },
          "certificate_nit": {
            "type": "string"
          },
          "mh_login_ok": {
            "type": "boolean"
          },
          "checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "mh_user": {
            "type": "string",
            "description": "NIT del usuario de la API del MH (no es secreto)"
          },
          "certificate_valid_until": {
            "type": "string",
            "format": "date-time"
          },
          "message": {
            "type": "string",
            "description": "Resultado legible de la última validación o prueba de conexión"
          }
        }
      },
      "Establishment": {
        "type": "object",
        "required": [
          "code",
          "type",
          "address"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Código MH (M001, S001, …)"
          },
          "name": {
            "type": "string",
            "description": "Nombre interno de la sucursal"
          },
          "type": {
            "type": "string",
            "description": "CAT-009"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "active": {
            "type": "boolean",
            "default": true
          },
          "points_of_sale": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "active": {
                  "type": "boolean",
                  "default": true
                }
              }
            }
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventType"
            }
          },
          "secret": {
            "type": "string",
            "description": "Solo al crear. Firma HMAC-SHA256 en header Sudte-Signature (t=…,v1=…)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_delivery_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_delivery_status": {
            "type": "integer",
            "description": "Código HTTP de la última entrega (0 si no hubo respuesta)"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "prefix": {
            "type": "string",
            "examples": [
              "sk_live_a1b2"
            ]
          },
          "secret": {
            "type": "string",
            "description": "Solo al crear"
          },
          "last_used_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "emitter_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Vacío o ausente = todos los emisores de la cuenta"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string"
          },
          "included": {
            "type": "integer"
          },
          "processed": {
            "type": "integer"
          },
          "by_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "rejected": {
            "type": "integer",
            "description": "Rechazados por MH (no se cobran)"
          },
          "sandbox": {
            "type": "integer",
            "description": "Procesados en ambiente 00 (no se cobran)"
          },
          "overage": {
            "type": "integer",
            "description": "Documentos sobre lo incluido en el plan"
          },
          "by_emitter": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "emitter_id": {
                  "type": "string"
                },
                "emitter_name": {
                  "type": "string"
                },
                "processed": {
                  "type": "integer"
                },
                "rejected": {
                  "type": "integer"
                }
              }
            }
          },
          "by_day": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "processed": {
                  "type": "integer"
                },
                "rejected": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "Billing": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "price": {
                "$ref": "#/components/schemas/Money"
              },
              "included_documents": {
                "type": "integer"
              },
              "overage_price": {
                "$ref": "#/components/schemas/Money"
              }
            }
          },
          "payment_method": {
            "type": "object",
            "properties": {
              "brand": {
                "type": "string"
              },
              "last4": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "card",
                  "transfer",
                  "none"
                ]
              }
            }
          },
          "subscription": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "trialing",
                  "active",
                  "past_due",
                  "cancelled"
                ]
              },
              "current_period_start": {
                "type": "string",
                "format": "date"
              },
              "current_period_end": {
                "type": "string",
                "format": "date"
              },
              "next_charge_at": {
                "type": "string",
                "format": "date"
              }
            }
          },
          "invoices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "period": {
                  "type": "string"
                },
                "total": {
                  "$ref": "#/components/schemas/Money"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "open",
                    "paid",
                    "void"
                  ]
                },
                "dte_document_id": {
                  "type": "string",
                  "description": "DTE que sudte emitió por este cobro"
                },
                "dte_control_number": {
                  "type": "string",
                  "description": "Número de control del DTE de sudte por este cobro"
                },
                "dte_pdf_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "PDF del DTE de sudte (el documento pertenece a la cuenta de TSA, por eso se expone como URL)"
                },
                "dte_json_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "JSON firmado del DTE de sudte"
                },
                "pay_url": {
                  "type": "string",
                  "format": "uri"
                },
                "number": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "subtotal": {
                  "$ref": "#/components/schemas/Money"
                },
                "iva": {
                  "$ref": "#/components/schemas/Money"
                },
                "issued_at": {
                  "type": "string",
                  "format": "date"
                },
                "due_at": {
                  "type": "string",
                  "format": "date"
                },
                "paid_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "FiscalRecord": {
        "type": "object",
        "description": "Compra recibida (`purchases`), retención/percepción recibida (`withholdings-received`) o venta no emitida\npor sudte (`external-sales`). Campos por tipo en `docs/research/reportes-fiscales.md` §6.1.\n",
        "required": [
          "external_id",
          "version",
          "accounting_date"
        ],
        "properties": {
          "external_id": {
            "type": "string",
            "examples": [
              "odoo:<db_uuid>:account.move:1542"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "source": {
            "type": "string",
            "enum": [
              "odoo",
              "manual",
              "csv"
            ],
            "default": "odoo"
          },
          "accounting_date": {
            "type": "string",
            "format": "date"
          },
          "issue_date": {
            "type": "string",
            "format": "date"
          },
          "doc_class": {
            "type": "string",
            "enum": [
              "1",
              "2",
              "3",
              "4"
            ],
            "description": "1 físico, 2 formulario único, 3 póliza/DUCA, 4 DTE"
          },
          "doc_type": {
            "type": "string",
            "description": "CAT-002"
          },
          "generation_code": {
            "type": "string"
          },
          "control_number": {
            "type": "string"
          },
          "seal": {
            "type": "string"
          },
          "counterpart": {
            "type": "object",
            "description": "Proveedor, cliente o agente según el recurso",
            "properties": {
              "name": {
                "type": "string"
              },
              "nit": {
                "type": "string"
              },
              "nrc": {
                "type": "string"
              },
              "dui": {
                "type": "string"
              },
              "country_code": {
                "type": "string"
              }
            }
          },
          "amounts": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Money"
            }
          },
          "attributes": {
            "type": "object",
            "description": "Clasificaciones (gasto, origen, kind de retención, applied_to, etc.)"
          },
          "exclude_from_books": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "FiscalBatchResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "external_id": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "updated",
                    "unchanged",
                    "error"
                  ]
                },
                "error": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "FiscalTags": {
        "type": "object",
        "properties": {
          "income_codes": {
            "type": "object",
            "properties": {
              "operation_type": {
                "type": "string"
              },
              "income_type": {
                "type": "string"
              }
            }
          },
          "free_zone": {
            "type": "boolean"
          },
          "exempt_non_proportional": {
            "type": "boolean"
          },
          "exclude_from_books": {
            "type": "boolean"
          },
          "external_ref": {
            "type": "string"
          }
        }
      },
      "FiscalReportType": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "libro_contribuyentes",
              "libro_consumidor",
              "libro_compras",
              "anexo_1",
              "anexo_2",
              "anexo_invalidaciones"
            ]
          },
          "title": {
            "type": "string"
          },
          "periodicity": {
            "type": "string",
            "enum": [
              "monthly",
              "semiannual"
            ]
          },
          "params_schema": {
            "type": "object",
            "description": "JSON Schema de parámetros para generar el formulario"
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx",
                "pdf",
                "zip"
              ]
            }
          }
        }
      },
      "FiscalReport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "emitter_id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "period": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "ready",
              "failed"
            ]
          },
          "period_status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ]
          },
          "input_hash": {
            "type": "string"
          },
          "rules_version": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "totals": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Money"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "document_id": {
                  "type": "string"
                }
              }
            }
          },
          "drift": {
            "type": "boolean",
            "description": "Periodo cerrado con cambios posteriores en las entradas"
          }
        }
      },
      "FiscalReportRows": {
        "type": "object",
        "properties": {
          "columns": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "date",
                    "money",
                    "int"
                  ]
                },
                "align": {
                  "type": "string"
                },
                "width": {
                  "type": "integer"
                },
                "group": {
                  "type": "string"
                }
              }
            }
          },
          "header_groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "totals": {
            "type": "object"
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "columns": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                },
                "rows": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "page": {
            "type": "integer"
          },
          "total_rows": {
            "type": "integer"
          }
        }
      },
      "FiscalPeriod": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closing",
              "closed"
            ]
          },
          "version": {
            "type": "integer"
          },
          "closed_at": {
            "type": "string",
            "format": "date-time"
          },
          "drift": {
            "type": "boolean"
          }
        }
      },
      "Problem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "mh": {
            "type": "object",
            "properties": {
              "codigoMsg": {
                "type": "string"
              },
              "descripcionMsg": {
                "type": "string"
              },
              "observaciones": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "NumberingSequence": {
        "type": "object",
        "properties": {
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "scope": {
            "type": "string",
            "description": "`*` = centralizada; o código MH del establecimiento (M001…)"
          },
          "year": {
            "type": "integer"
          },
          "last_value": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "maximum": 999999999999999
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Catalog": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "CAT-012"
            ]
          },
          "name": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "code",
                "name"
              ],
              "properties": {
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "department": {
                  "type": "string",
                  "description": "CAT-013 y CAT-008: código CAT-012 del departamento"
                },
                "municipality": {
                  "type": "string",
                  "description": "CAT-008: código CAT-013 del municipio (único dentro del departamento)"
                }
              }
            }
          }
        }
      },
      "Plan": {
        "type": "object",
        "required": [
          "code",
          "name",
          "price",
          "included_documents"
        ],
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "starter"
            ]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "price": {
            "$ref": "#/components/schemas/Money",
            "description": "Mensual sin IVA (USD)"
          },
          "currency": {
            "type": "string",
            "default": "USD"
          },
          "included_documents": {
            "type": "integer"
          },
          "overage_price": {
            "$ref": "#/components/schemas/Money",
            "description": "Por documento procesado sobre lo incluido"
          },
          "max_emitters": {
            "type": "integer",
            "description": "0 = ilimitado"
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "public": {
            "type": "boolean",
            "default": true
          },
          "active": {
            "type": "boolean",
            "default": true
          },
          "subscribers": {
            "type": "integer",
            "description": "Solo admin"
          }
        }
      },
      "AccountStatus": {
        "type": "string",
        "enum": [
          "trialing",
          "active",
          "past_due",
          "suspended",
          "cancelled"
        ]
      },
      "UserRole": {
        "type": "string",
        "enum": [
          "owner",
          "admin",
          "developer",
          "accountant",
          "viewer"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "superadmin": {
            "type": "boolean",
            "description": "Personal de TSA con acceso a /admin"
          },
          "otp_enabled": {
            "type": "boolean"
          },
          "emitter_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restricción opcional a ciertos emisores"
          },
          "last_login_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/AccountStatus"
          },
          "plan_code": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Session": {
        "type": "object",
        "required": [
          "user",
          "account",
          "csrf_token"
        ],
        "properties": {
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "account": {
            "$ref": "#/components/schemas/Account"
          },
          "csrf_token": {
            "type": "string",
            "description": "Enviar en el header X-CSRF-Token en POST/PUT/PATCH/DELETE autenticados con cookie"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "impersonation": {
            "type": [
              "object",
              "null"
            ],
            "description": "Presente cuando un superadmin está viendo la cuenta de un cliente",
            "properties": {
              "admin_email": {
                "type": "string"
              },
              "account_id": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              },
              "started_at": {
                "type": "string",
                "format": "date-time"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        }
      },
      "RegisterInput": {
        "type": "object",
        "required": [
          "name",
          "email",
          "password",
          "company_name",
          "accept_terms"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "format": "password",
            "minLength": 10
          },
          "company_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 200
          },
          "phone": {
            "type": "string"
          },
          "accept_terms": {
            "type": "boolean",
            "const": true
          }
        }
      },
      "MhStatus": {
        "type": "object",
        "properties": {
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down",
              "unknown"
            ]
          },
          "latency_p50_ms": {
            "type": "integer"
          },
          "latency_p95_ms": {
            "type": "integer"
          },
          "success_rate": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Últimos 15 minutos"
          },
          "last_checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_error": {
            "type": "string"
          }
        }
      },
      "QueueStatus": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "examples": [
              "transmission",
              "webhooks",
              "email",
              "fiscal"
            ]
          },
          "available": {
            "type": "integer"
          },
          "running": {
            "type": "integer"
          },
          "retryable": {
            "type": "integer"
          },
          "scheduled": {
            "type": "integer"
          },
          "discarded": {
            "type": "integer"
          },
          "oldest_available_seconds": {
            "type": "integer"
          }
        }
      },
      "AdminDashboard": {
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "revenue": {
            "type": "object",
            "properties": {
              "mrr": {
                "$ref": "#/components/schemas/Money"
              },
              "month_to_date": {
                "$ref": "#/components/schemas/Money"
              },
              "outstanding": {
                "$ref": "#/components/schemas/Money"
              },
              "overdue_invoices": {
                "type": "integer"
              }
            }
          },
          "accounts": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "active": {
                "type": "integer"
              },
              "trialing": {
                "type": "integer"
              },
              "past_due": {
                "type": "integer"
              },
              "suspended": {
                "type": "integer"
              }
            }
          },
          "totals": {
            "type": "object",
            "description": "Totales del rango de días",
            "properties": {
              "processed": {
                "type": "integer"
              },
              "rejected": {
                "type": "integer"
              },
              "contingency": {
                "type": "integer"
              },
              "error": {
                "type": "integer"
              }
            }
          },
          "documents_by_day": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "processed": {
                  "type": "integer"
                },
                "rejected": {
                  "type": "integer"
                },
                "contingency": {
                  "type": "integer"
                }
              }
            }
          },
          "mh_status": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MhStatus"
            }
          },
          "queues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QueueStatus"
            }
          }
        }
      },
      "AdminAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "owner_name": {
            "type": "string"
          },
          "owner_email": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/AccountStatus"
          },
          "plan_code": {
            "type": "string"
          },
          "emitters_count": {
            "type": "integer"
          },
          "documents_month": {
            "type": "integer"
          },
          "outstanding": {
            "$ref": "#/components/schemas/Money"
          },
          "notes": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AdminAccountDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AdminAccount"
          },
          {
            "type": "object",
            "properties": {
              "emitters": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Emitter"
                }
              },
              "users": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/User"
                }
              },
              "subscription": {
                "$ref": "#/components/schemas/Subscription"
              },
              "usage": {
                "$ref": "#/components/schemas/Usage"
              },
              "invoices": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AdminInvoice"
                }
              }
            }
          }
        ]
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "account_id": {
            "type": "string"
          },
          "account_name": {
            "type": "string"
          },
          "plan_code": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "trialing",
              "active",
              "past_due",
              "cancelled"
            ]
          },
          "payment_provider": {
            "type": "string",
            "examples": [
              "manual",
              "wompi",
              "n1co"
            ]
          },
          "payment_method": {
            "type": "object",
            "properties": {
              "brand": {
                "type": "string"
              },
              "last4": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "card",
                  "transfer",
                  "none"
                ]
              }
            }
          },
          "current_period_start": {
            "type": "string",
            "format": "date"
          },
          "current_period_end": {
            "type": "string",
            "format": "date"
          },
          "next_charge_at": {
            "type": "string",
            "format": "date"
          },
          "cancel_at": {
            "type": "string",
            "format": "date"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AdminInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "account_id": {
            "type": "string"
          },
          "account_name": {
            "type": "string"
          },
          "period": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "iva": {
            "$ref": "#/components/schemas/Money"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "paid",
              "void"
            ]
          },
          "due_at": {
            "type": "string",
            "format": "date"
          },
          "paid_at": {
            "type": "string",
            "format": "date-time"
          },
          "payment_method": {
            "type": "string",
            "enum": [
              "card",
              "transfer",
              "cash",
              "check",
              "other"
            ]
          },
          "payment_reference": {
            "type": "string"
          },
          "payment_attempts": {
            "type": "integer"
          },
          "last_payment_error": {
            "type": "string"
          },
          "dte_document_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AdminUsageRow": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string"
          },
          "account_name": {
            "type": "string"
          },
          "plan_code": {
            "type": "string"
          },
          "included": {
            "type": "integer"
          },
          "processed": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "sandbox": {
            "type": "integer"
          },
          "overage": {
            "type": "integer"
          },
          "overage_amount": {
            "$ref": "#/components/schemas/Money"
          },
          "by_emitter": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "emitter_id": {
                  "type": "string"
                },
                "emitter_name": {
                  "type": "string"
                },
                "nit": {
                  "type": "string"
                },
                "processed": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "AdminDocument": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Document"
          },
          {
            "type": "object",
            "properties": {
              "account_id": {
                "type": "string"
              },
              "account_name": {
                "type": "string"
              }
            }
          }
        ]
      },
      "AuditEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "actor_id": {
            "type": "string"
          },
          "actor_email": {
            "type": "string"
          },
          "action": {
            "type": "string",
            "examples": [
              "impersonation.start",
              "impersonation.stop",
              "invoice.mark_paid",
              "invoice.retry",
              "account.update",
              "plan.update"
            ]
          },
          "account_id": {
            "type": "string"
          },
          "target_type": {
            "type": "string"
          },
          "target_id": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "ip": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          }
        }
      }
    }
  }
}
