openapi: 3.0.3
info:
  title: TEP — Transactional Email Platform API
  description: |
    API REST para envio e rastreamento de e-mails transacionais da plataforma Laniway TEP.

    **Autenticação**

    Todos os endpoints (exceto `GET /health` e `GET /auth/cache/sweep-1.0`) requerem um
    token de acesso **LIAM** (Laniway Identity and Access Management) no header `Authorization: Bearer <token>`.

    **Códigos de erro**

    Todos os erros retornam o formato:
    ```json
    { "code": 1000001, "message": "..." }
    ```

    Consulte a seção de schemas para a lista completa de códigos de erro.
  version: "1.0.0"
  contact:
    name: Laniway Platform Team
    email: itm@laniway.com

servers:
  - url: https://api.tep.laniway.com.br
    description: Produção
  - url: https://api.tep.laniway.com
    description: Produção (alias)

tags:
  - name: system
    description: Endpoints de sistema (health, auth cache sweep)
  - name: message
    description: Envio e consulta de mensagens
  - name: domain
    description: Gestão de configuração por domínio (DKIM)

paths:

  /health:
    get:
      summary: Health check
      description: Verifica se a API está operacional e retorna o IP observado do caller. Não requer autenticação.
      operationId: health
      tags: [system]
      responses:
        "200":
          description: API operacional
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthResponse"
              example:
                status: ok
                caller_ip: 203.0.113.10

  /auth/cache/sweep-1.0:
    get:
      summary: Sweep de cache de autenticação LIAM
      description: |
        Revalida proativamente tokens em cache com o LIAM e evicta entradas inativas.
        Chamado internamente pelo HAProxy a cada 30s em cada worker. Não requer autenticação.
      operationId: authCacheSweep
      tags: [system]
      responses:
        "200":
          description: Serviço ativo
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthCacheSweepResponse"
              example:
                status: ok

  /message/add-1.0:
    post:
      summary: Adicionar mensagem para envio
      description: |
        Cria uma mensagem de e-mail transacional na fila de envio.

        **Formato do conteúdo** (`message_content_format`):

        | Formato     | Campo de conteúdo          | Aceita anexos | MIME resultante |
        |-------------|----------------------------|---------------|-----------------|
        | `text_only` | `message_text_content`     | Não            | `text/plain` |
        | `html_only` | `message_html_content`     | Sim           | `multipart/mixed` (HTML + anexos) ou `text/html` |
        | `mixed`     | `message_text_content` + `message_html_content` | Sim | `multipart/mixed` com `multipart/alternative` interno |
        | `EML`       | `message_raw_content`      | Não            | mensagem EML já montada (raw) |

        Enviar `message_attachments` com `text_only` ou `EML` resulta em HTTP 400.

        **Anexos** (`message_attachments`): cada item deve conter `filename`, `content_type` e
        `data` (conteúdo do arquivo em Base64). Requer a sub-permissão `tep.message.send.attachment`.

        **Agendamento** (`message_delivery_time`):
        - `immediate` (padrão) — envia imediatamente
        - `scheduled` — envia após `message_delivery_after` (ISO 8601)
        - `manual-wait` — aguarda confirmação manual para envio
        - `manual-cancel` — cancela a mensagem
        - `manual-send` — força envio imediato
      operationId: messageAdd
      tags: [message]
      security:
        - liamBearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageAddRequest"
            example:
              message_sender: "noreply@laniway.com"
              message_from:
                - name: "Laniway Platform"
                  address: "noreply@laniway.com"
              message_subject: "Sua solicitação foi processada"
              message_to:
                - name: "João Silva"
                  address: "joao@example.com"
              message_content_format: "mixed"
              message_text_content: "Olá João, sua solicitação foi processada com sucesso."
              message_html_content: "<p>Olá <b>João</b>, sua solicitação foi processada com sucesso.</p>"
      responses:
        "200":
          description: Mensagem adicionada com sucesso
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageAddResponse"
              example:
                meta:
                  code: 200
                  action: message/add-1.0
                data:
                  message_uuid: "01940100-1234-7abc-8def-000000000001"
                  status: queued
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/SenderNotAuthorized"
        "500":
          $ref: "#/components/responses/StorageFailure"

  /message/delete-1.0:
    post:
      summary: Excluir mensagens
      description: |
        Exclui uma ou mais mensagens pertencentes ao usuário autenticado.

        **Regras de ownership:** Para cada UUID informado, a API valida que a mensagem pertence
        ao `identity_id` do token. Usuários com a permissão `tep.message.delete.all`
        podem excluir mensagens de qualquer identity.

        **Compliance — mensagens transmitidas:** Mensagens com status `processing`, `sent`, `delivered`
        ou `bounced` **nunca** são excluídas por padrão, independente de qualquer outra permissão.
        A permissão `tep.message.delete.transmitted` bypassa essa proteção e é de uso exclusivo
        de equipe interna (role `role-tep-staff-master`) ou sistemas autorizados (app_token).
        Nunca deve ser concedida a administradores de tenant.

        O objeto de body armazenado em S3 é removido junto com o registro.
        A operação é atômica por mensagem: falhas de ownership, not_found ou proteção de
        compliance não interrompem a exclusão das demais.
      operationId: messageDelete
      tags: [message]
      security:
        - liamBearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageDeleteRequest"
            examples:
              bulk:
                summary: Excluir múltiplas mensagens
                value:
                  message_uuids:
                    - "01940100-1234-7abc-8def-000000000001"
                    - "01940101-5678-7abc-8def-000000000002"
      responses:
        "200":
          description: Resultado da exclusão (parcial ou total)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageDeleteResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"

  /message/query-1.0:
    post:
      summary: Consultar mensagens
      description: |
        Consulta mensagens enviadas pelo usuário autenticado.
        Todas as consultas são automaticamente isoladas por `tenant_id` e `identity_id` (baseados no token LIAM).
        Usuários com a permissão `tep.message.read.all` podem visualizar mensagens de todos os
        identities dentro do mesmo tenant (visibilidade administrativa).

        É possível consultar por `message_uuid` específico (retorna detalhes completos incluindo
        destinatários e histórico de status) ou aplicar filtros por
        `message_status`, `message_date_from`, `message_date_to` e `message_limit` (retorna resumos).
        Todos os parâmetros são opcionais.
      operationId: messageQuery
      tags: [message]
      security:
        - liamBearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageQueryRequest"
            examples:
              byUUID:
                summary: Busca por UUID
                value:
                  message_uuid: "01940100-1234-7abc-8def-000000000001"
              byFilter:
                summary: Busca por filtros
                value:
                  message_status: sent
                  message_date_from: "2026-03-01T00:00:00Z"
                  message_date_to: "2026-03-31T23:59:59Z"
                  message_limit: 50
      responses:
        "200":
          description: Lista de mensagens encontradas
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageQueryResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/MessageNotFound"

  /domain/dkim/status-1.0:
    get:
      summary: Consultar status DKIM do domínio
      description: |
        Retorna a configuração DKIM do TEP para o domínio (`tep_config`).

        `tep_config` é `null` quando o domínio não possui configuração DKIM explícita
        no TEP (i.e., nunca passou por `set-algorithm` e o TEP ainda não iniciou envio
        por este domínio). A presença de um domínio no LAM3 não é suficiente para gerar
        `tep_config`.

        A consulta é sempre isolada ao tenant do token autenticado.
      operationId: domainDkimStatus
      tags: [domain]
      security:
        - liamBearerAuth: []
      parameters:
        - name: domain_name
          in: query
          required: true
          schema:
            type: string
            maxLength: 253
          example: example.com.br
      responses:
        "200":
          description: Status DKIM retornado com sucesso
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DkimStatusResponse"
              example:
                meta:
                  code: 200
                  action: domain/dkim/status-1.0
                data:
                  domain: example.com.br
                  tep_config:
                    dkim_enabled: 1
                    dkim_algorithm: ed25519
                    dkim_selector: tep-a1b2c3d4
                    dkim_dns_status: active
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"

  /domain/dkim/set-algorithm-1.0:
    post:
      summary: Configurar algoritmo DKIM do domínio
      description: |
        Altera o algoritmo DKIM preferido e/ou habilita ou desabilita a assinatura DKIM
        para um domínio.

        Ao alterar o algoritmo, o cache local é limpo e uma nova chave LAM3
        com o algoritmo solicitado será selecionada (ou criada) automaticamente
        na próxima mensagem enviada pelo domínio.

        Se o domínio não tiver configuração prévia, ela é criada com os valores fornecidos.

        **Campos opcionais:** `algorithm` e `dkim_enabled` são independentes —
        é possível apenas desabilitar DKIM sem trocar o algoritmo, ou apenas
        trocar o algoritmo sem alterar o estado de habilitado.
      operationId: domainDkimSetAlgorithm
      tags: [domain]
      security:
        - liamBearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DkimSetAlgorithmRequest"
            examples:
              changeToRsa:
                summary: Trocar para RSA-1024
                value:
                  domain_name: example.com.br
                  algorithm: rsa-1024
              disableDkim:
                summary: Desabilitar assinatura DKIM
                value:
                  domain_name: example.com.br
                  dkim_enabled: 0
              enableAndSetAlgo:
                summary: Habilitar e definir algoritmo
                value:
                  domain_name: example.com.br
                  algorithm: ed25519
                  dkim_enabled: 1
      responses:
        "200":
          description: Configuração DKIM atualizada com sucesso
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DkimSetAlgorithmResponse"
              example:
                meta:
                  code: 200
                  action: domain/dkim/set-algorithm-1.0
                data:
                  domain: example.com.br
                  tep_config:
                    dkim_algorithm: rsa-1024
                    dkim_enabled: 1
        "400":
          $ref: "#/components/responses/InvalidAlgorithm"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"

  /domain/dkim/revalidate-1.0:
    post:
      summary: Forçar re-verificação de status DKIM
      description: |
        Zera o TTL de verificação DKIM do domínio, forçando uma nova consulta
        ao LAM3 na próxima mensagem enviada pelo domínio.

        Útil após rotação manual de chave no LAM3 ou após correção de registro DNS,
        quando não se quer aguardar o TTL natural (`TEP_DKIM_VERIFY_TTL_HOURS`, padrão 6h).

        O domínio deve ter uma configuração prévia (ter enviado pelo menos uma mensagem
        ou ter passado por `set-algorithm`). Caso contrário, retorna 404.
      operationId: domainDkimRevalidate
      tags: [domain]
      security:
        - liamBearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DkimRevalidateRequest"
            example:
              domain_name: example.com.br
      responses:
        "200":
          description: Re-validação agendada para a próxima mensagem
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DkimRevalidateResponse"
              example:
                meta:
                  code: 200
                  action: domain/dkim/revalidate-1.0
                data:
                  domain: example.com.br
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/DomainNotFound"

components:

  securitySchemes:
    liamBearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Token de acesso LIAM (Laniway Identity and Access Management)

  schemas:

    Meta:
      type: object
      description: Metadados padrão de resposta BrokerNG
      properties:
        code:
          type: integer
          example: 200
        action:
          type: string
          example: message/add-1.0
      required: [code, action]

    HealthResponse:
      type: object
      required: [status, caller_ip]
      properties:
        status:
          type: string
          example: ok
        caller_ip:
          type: string
          nullable: true
          description: Caller IP address observed by the platform
          example: 203.0.113.10

    AuthCacheSweepResponse:
      type: object
      properties:
        status:
          type: string
          example: ok

    EmptyDataResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          example: {}

    EmailAddress:
      type: object
      required: [address]
      properties:
        name:
          type: string
          description: Nome de exibição
          example: "João Silva"
        address:
          type: string
          format: email
          description: Endereço de e-mail
          example: "joao@example.com"

    Attachment:
      type: object
      required: [filename, content_type, data]
      properties:
        filename:
          type: string
          example: "relatorio.pdf"
        content_type:
          type: string
          example: "application/pdf"
        data:
          type: string
          format: byte
          description: Conteúdo do arquivo em Base64

    MessageAddRequest:
      type: object
      required: [message_sender, message_from, message_subject, message_to]
      properties:
        message_sender:
          type: string
          format: email
          description: Endereço de envio (envelope sender / Return-Path)
          maxLength: 254
        message_from:
          type: array
          description: Cabeçalho From (de 1 a 5 endereços)
          minItems: 1
          maxItems: 5
          items:
            $ref: "#/components/schemas/EmailAddress"
        message_subject:
          type: string
          description: Assunto da mensagem
          maxLength: 255
        message_to:
          type: array
          description: Destinatários (até 100)
          minItems: 1
          maxItems: 100
          items:
            $ref: "#/components/schemas/EmailAddress"
        message_cc:
          type: array
          description: Destinatários em cópia (até 100)
          maxItems: 100
          items:
            $ref: "#/components/schemas/EmailAddress"
        message_bcc:
          type: array
          description: Destinatários em cópia oculta (até 100)
          maxItems: 100
          items:
            $ref: "#/components/schemas/EmailAddress"
        message_reply_to:
          type: array
          description: Endereços de resposta (até 5)
          maxItems: 5
          items:
            $ref: "#/components/schemas/EmailAddress"
        message_delivery_time:
          type: string
          description: Estratégia de entrega
          enum: [immediate, scheduled, manual-wait, manual-cancel, manual-send]
          default: immediate
        message_delivery_after:
          type: string
          format: date-time
          description: Data/hora de entrega agendada (ISO 8601). Usado com `message_delivery_time=scheduled`.
        message_delivery_timeout:
          type: integer
          description: Timeout de entrega em minutos (1–43200)
          minimum: 1
          maximum: 43200
        message_content_format:
          type: string
          description: |
            Formato do conteúdo da mensagem. Determina quais campos de conteúdo são esperados
            e se anexos são aceitos.
            - `text_only` — `message_text_content`. **Não aceita anexos.**
            - `html_only` — `message_html_content`. Aceita `message_attachments`.
            - `mixed` — `message_text_content` + `message_html_content`. Aceita `message_attachments`.
            - `EML` — `message_raw_content` (mensagem já montada). **Não aceita anexos.**
          enum: [text_only, html_only, mixed, EML]
          default: text_only
        message_text_content:
          type: string
          description: Corpo em texto simples. Obrigatório para `text_only` e `mixed`.
          maxLength: 1000000
        message_html_content:
          type: string
          description: Corpo em HTML. Obrigatório para `html_only` e `mixed`.
          maxLength: 5000000
        message_raw_content:
          type: string
          description: Mensagem EML completa (raw). Obrigatório para `EML`.
          maxLength: 10000000
        message_attachments:
          type: array
          description: |
            Anexos da mensagem (máximo 50). Suportado apenas nos formatos `html_only` e `mixed`.
            Requer a sub-permissão `tep.message.send.attachment`. Cada item deve conter
            `filename`, `content_type` e `data` (conteúdo em Base64).
          maxItems: 50
          items:
            $ref: "#/components/schemas/Attachment"

    MessageAddResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            message_uuid:
              type: string
              format: uuid
              description: UUID v7 da mensagem criada
            status:
              type: string
              enum: [queued]
              description: Status inicial da mensagem

    MessageDeleteRequest:
      type: object
      required: [message_uuids]
      properties:
        message_uuids:
          type: array
          description: "Lista de UUIDs das mensagens a excluir (máximo recomendado: 100)."
          items:
            type: string
            format: uuid

    MessageDeleteResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            deleted:
              type: array
              description: UUIDs excluídos com sucesso.
              items:
                type: string
                format: uuid
            not_found:
              type: array
              description: UUIDs não encontrados no tenant informado.
              items:
                type: string
                format: uuid
            unauthorized:
              type: array
              description: UUIDs que pertencem a outro identity (sem permissão tep.message.delete.all).
              items:
                type: string
                format: uuid
            protected:
              type: array
              description: |
                UUIDs bloqueados por compliance — mensagem já transmitida (status processing/sent/delivered/bounced).
                Requer a permissão `tep.message.delete.transmitted` para excluir.
              items:
                type: string
                format: uuid
            failed:
              type: array
              description: UUIDs que não puderam ser excluídos por erro interno. Nenhum dado foi removido para estes itens — a operação pode ser repetida.
              items:
                type: string
                format: uuid

    MessageQueryRequest:
      type: object
      properties:
        message_uuid:
          type: string
          format: uuid
          description: UUID v7 de uma mensagem específica
          maxLength: 36
        message_status:
          type: string
          description: Filtro por status da mensagem
          enum: [queued, processing, sent, delivered, bounced, failed, cancelled, expired]
        message_date_from:
          type: string
          format: date-time
          description: Data de início do filtro (ISO 8601)
        message_date_to:
          type: string
          format: date-time
          description: Data de fim do filtro (ISO 8601)
        message_limit:
          type: integer
          description: Número máximo de resultados (1–1000)
          minimum: 1
          maximum: 1000
          default: 100

    MessageRecord:
      type: object
      description: Resumo de mensagem retornado na listagem por filtros
      properties:
        message_uuid:
          type: string
          format: uuid
        tenant_id:
          type: string
        sender:
          type: string
          format: email
        subject:
          type: string
        content_format:
          type: string
          enum: [text_only, html_only, mixed, EML]
        delivery_time:
          type: string
          enum: [immediate, scheduled, manual-wait, manual-cancel, manual-send]
        current_status:
          type: string
          enum: [queued, processing, sent, delivered, bounced, failed, cancelled, expired]
        created_at:
          type: string
          format: date-time
          example: "2026-03-20T14:30:00-03:00"

    MessageDetailRecord:
      type: object
      description: Detalhes completos de mensagem retornados na consulta por UUID
      properties:
        message_uuid:
          type: string
          format: uuid
        tenant_id:
          type: string
        sender:
          type: string
          format: email
        subject:
          type: string
        content_format:
          type: string
          enum: [text_only, html_only, mixed, EML]
        delivery_time:
          type: string
          enum: [immediate, scheduled, manual-wait, manual-cancel, manual-send]
        created_at:
          type: string
          format: date-time
          example: "2026-03-20T14:30:00-03:00"
        updated_at:
          type: string
          format: date-time
          example: "2026-03-20T15:00:00-03:00"
        current_status:
          type: string
          enum: [queued, processing, sent, delivered, bounced, failed, cancelled, expired]
        from:
          type: array
          items:
            $ref: "#/components/schemas/EmailAddress"
        recipients:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                enum: [to, cc, bcc]
              address:
                type: string
                format: email
              name:
                type: string
        status_history:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              detail:
                type: string
              created_at:
                type: string
                format: date-time
                example: "2026-03-20T14:30:00-03:00"

    MessageQueryResponse:
      type: object
      description: |
        Quando `message_uuid` é informado, retorna um objeto `message` com detalhes completos.
        Quando filtros são usados, retorna um array `messages` com resumos.
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            message:
              allOf:
                - $ref: "#/components/schemas/MessageDetailRecord"
              description: Presente quando consultado por UUID
            messages:
              type: array
              description: Presente quando consultado por filtros
              items:
                $ref: "#/components/schemas/MessageRecord"
            count:
              type: integer
              description: Quantidade de mensagens retornadas (filtros)

    DkimKeyRecord:
      type: object
      description: Chave DKIM registrada
      properties:
        dkim_id:
          type: string
          format: uuid
          description: Identificador único da chave no LAM3
        dkim_selector:
          type: string
          description: Seletor DNS (ex. tep-a1b2c3d4)
          example: tep-a1b2c3d4
        dkim_purpose:
          type: string
          description: Finalidade da chave (tep, smtp, external, etc.)
          example: tep
        dkim_algorithm:
          type: string
          enum: [ed25519, rsa-1024]
          example: ed25519
        dkim_status:
          type: string
          enum: [active, inactive, dns_pending, pending_remove]
          example: active
        dns_published:
          type: boolean
          description: Indica se o registro DNS já foi propagado
          example: true

    DkimStatusResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            domain:
              type: string
              example: example.com.br
            tep_config:
              type: object
              nullable: true
              description: |
                Configuração DKIM do TEP para este domínio. `null` quando o domínio
                ainda não possui configuração (nunca enviou mensagem nem chamou set-algorithm).
              properties:
                dkim_enabled:
                  type: integer
                  description: "1 = assinatura DKIM habilitada (padrão); 0 = desabilitada pelo usuário"
                  enum: [0, 1]
                  example: 1
                dkim_algorithm:
                  type: string
                  nullable: true
                  description: Algoritmo configurado para o domínio (null = não definido explicitamente; padrão ed25519 será usado ao enviar)
                  enum: [ed25519, rsa-1024]
                  example: ed25519
                dkim_selector:
                  type: string
                  nullable: true
                  description: Seletor DNS em uso (null se nenhuma chave cacheada ainda)
                  example: tep-a1b2c3d4
                dkim_dns_status:
                  type: string
                  nullable: true
                  description: Último status DNS conhecido (null se nunca verificado)
                  enum: [active, inactive, dns_pending, pending_remove]
                  example: active

    DkimSetAlgorithmRequest:
      type: object
      required: [domain_name]
      properties:
        domain_name:
          type: string
          description: Nome do domínio a configurar
          maxLength: 253
          example: example.com.br
        algorithm:
          type: string
          description: |
            Algoritmo DKIM preferido. Ao alterar, o cache local é limpo e
            uma nova chave LAM3 com o algoritmo solicitado será usada na
            próxima mensagem. Se omitido, não altera o algoritmo atual.
          enum: [ed25519, rsa-1024]
          example: ed25519
        dkim_enabled:
          type: integer
          description: |
            `1` para habilitar assinatura DKIM (padrão), `0` para desabilitar.
            Se omitido, não altera o estado atual.
          enum: [0, 1]
          example: 1

    DkimSetAlgorithmResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            domain:
              type: string
              example: example.com.br
            tep_config:
              type: object
              properties:
                dkim_algorithm:
                  type: string
                  enum: [ed25519, rsa-1024]
                  example: ed25519
                dkim_enabled:
                  type: integer
                  enum: [0, 1]
                  example: 1

    DkimRevalidateRequest:
      type: object
      required: [domain_name]
      properties:
        domain_name:
          type: string
          description: Nome do domínio a re-validar
          maxLength: 253
          example: example.com.br

    DkimRevalidateResponse:
      type: object
      properties:
        meta:
          $ref: "#/components/schemas/Meta"
        data:
          type: object
          properties:
            domain:
              type: string
              example: example.com.br

    ErrorResponse:
      type: object
      properties:
        code:
          type: integer
          description: Código de erro TEP
        message:
          type: string
          description: Descrição do erro

  responses:

    Unauthorized:
      description: Token LIAM não autenticado ou inválido
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1000001
            message: The current SSO token is not authenticated

    Forbidden:
      description: Token LIAM não corresponde ao e-mail solicitado / remetente não autorizado
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1000002
            message: The current SSO token does not match with the requested e-mail address

    BadRequest:
      description: Parâmetros inválidos
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            invalidFormat:
              value:
                code: 1001002
                message: Invalid content format
            invalidTimeout:
              value:
                code: 1001003
                message: Delivery timeout invalid
            invalidRecipients:
              value:
                code: 1001007
                message: Invalid recipients

    SenderNotAuthorized:
      description: Endereço de remetente não autorizado para este usuário
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1001004
            message: Sender address not authorized

    StorageFailure:
      description: Falha ao armazenar conteúdo no S3
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1001006
            message: Storage failure

    MessageNotFound:
      description: Mensagem não encontrada
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1001001
            message: Message not found

    DomainNotFound:
      description: Domínio não encontrado na configuração do tenant
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1002003
            message: Domain not found in configuration

    InvalidAlgorithm:
      description: Valor de algoritmo inválido
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          example:
            code: 1002002
            message: "Invalid algorithm value (allowed: ed25519, rsa-1024)"
