{
  "openapi": "3.0.3",
  "info": {
    "title": "Notifique API — WhatsApp",
    "description": "Envie mensagens WhatsApp e gerencie conexões. Autentique com `Authorization: Bearer sk_live_...` ou `x-api-key`.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.notifique.dev",
      "description": "Produção"
    }
  ],
  "security": [
    {
      "ntfWaBearerAuth": []
    },
    {
      "ntfWaApiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "Mensagens",
      "description": "Enviar, listar, editar e cancelar mensagens"
    },
    {
      "name": "Instâncias",
      "description": "Cadastre e gerencie os números de WhatsApp conectados — cada número é uma **instância** (o telefone por onde entram e saem as mensagens)."
    },
    {
      "name": "Grupos",
      "description": "Grupos (só conexão não oficial)"
    }
  ],
  "paths": {
    "/v1/whatsapp/messages": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Listar mensagens WhatsApp",
        "description": "Mostra o histórico de mensagens enviadas no WhatsApp. Dá para filtrar por data, status e tipo.",
        "operationId": "ntfWa_getV1WhatsappMessages",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "toDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "instanceIds",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "IDs separados por vírgula"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "QUEUED",
                "PROCESSING",
                "SENT",
                "DELIVERED",
                "READ",
                "FAILED",
                "CANCELLED",
                "SCHEDULED",
                "DELETED",
                "RESPONDED",
                "EDITED"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filtra por tipo de mensagem no histórico. **TEMPLATE** é tipo armazenado para modelos específicos; demais tipos refletem o que foi enviado pela API.",
            "schema": {
              "type": "string",
              "enum": [
                "TEXT",
                "IMAGE",
                "DOCUMENT",
                "AUDIO",
                "VIDEO",
                "BUTTONS",
                "LIST",
                "TEMPLATE",
                "LOCATION",
                "CONTACT"
              ]
            }
          },
          {
            "name": "includeEvents",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "true/1/yes para incluir eventos"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de mensagens e paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "messageId": "clxx123...",
                      "to": "5511999999999",
                      "type": "TEXT",
                      "status": "SENT",
                      "sentAt": "2025-02-20T12:00:00.000Z",
                      "deliveredAt": "2025-02-20T12:00:05.000Z",
                      "createdAt": "2025-02-20T11:59:58.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 42,
                    "page": 1,
                    "limit": 20,
                    "totalPages": 3
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância negado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Enviar mensagem WhatsApp",
        "description": "Envia mensagem no WhatsApp para um ou vários números. Pode ser texto, mídia, botões, lista ou template.",
        "operationId": "ntfWa_postV1WhatsappSend",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Chave única para idempotência. Alternativa: x-idempotency-key."
          },
          {
            "name": "x-idempotency-key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NtfWa_SendWhatsAppMessageRequest"
              },
              "examples": {
                "text": {
                  "summary": "Texto",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "text",
                    "payload": {
                      "message": "Olá!"
                    }
                  }
                },
                "image": {
                  "summary": "Imagem",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "image",
                    "payload": {
                      "mediaUrl": "https://example.com/image.jpg",
                      "fileName": "image.jpg",
                      "mimetype": "image/jpeg",
                      "caption": "Legenda opcional"
                    }
                  }
                },
                "video": {
                  "summary": "Vídeo",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "video",
                    "payload": {
                      "mediaUrl": "https://example.com/video.mp4",
                      "fileName": "video.mp4",
                      "mimetype": "video/mp4",
                      "caption": "Legenda opcional"
                    }
                  }
                },
                "audio": {
                  "summary": "Áudio",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "audio",
                    "payload": {
                      "mediaUrl": "https://example.com/audio.mp3",
                      "fileName": "audio.mp3",
                      "mimetype": "audio/mpeg"
                    }
                  }
                },
                "document": {
                  "summary": "Documento",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "document",
                    "payload": {
                      "mediaUrl": "https://example.com/file.pdf",
                      "fileName": "file.pdf",
                      "mimetype": "application/pdf"
                    }
                  }
                },
                "buttons": {
                  "summary": "Botões",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "buttons",
                    "payload": {
                      "title": "Confirmação",
                      "description": "Deseja continuar?",
                      "buttons": [
                        {
                          "type": "reply",
                          "displayText": "Sim",
                          "id": "btn_yes"
                        },
                        {
                          "type": "reply",
                          "displayText": "Não",
                          "id": "btn_no"
                        }
                      ]
                    }
                  },
                  "description": "Até 3 botões reply (ou só url / só call)."
                },
                "list": {
                  "summary": "Lista",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "list",
                    "payload": {
                      "title": "Menu",
                      "description": "Escolha uma opção",
                      "buttonText": "Ver opções",
                      "listSections": [
                        {
                          "title": "Principal",
                          "rows": [
                            {
                              "rowId": "opt_1",
                              "title": "Opção 1",
                              "description": "Detalhe"
                            },
                            {
                              "rowId": "opt_2",
                              "title": "Opção 2"
                            }
                          ]
                        }
                      ]
                    }
                  },
                  "description": "Lista interativa (máx. 10 linhas)."
                },
                "location": {
                  "summary": "Localização",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "location",
                    "payload": {
                      "latitude": -23.5505,
                      "longitude": -46.6333,
                      "name": "São Paulo",
                      "address": "São Paulo, SP"
                    }
                  }
                },
                "scheduled": {
                  "summary": "Agendada",
                  "value": {
                    "instanceId": "clxx...",
                    "to": [
                      "5511999999999"
                    ],
                    "type": "text",
                    "payload": {
                      "message": "Lembrete agendado."
                    },
                    "schedule": {
                      "sendAt": "2025-12-31T14:00:00.000Z"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Mensagem(ns) aceita(s). Enfileirada(s) ou agendada(s). Resposta padronizada com envelope success/data; status em MAIÚSCULO (QUEUED, SCHEDULED).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/NtfWa_SendWhatsAppMessageResponse"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "messageIds": [
                      "clxx1...",
                      "clxx2..."
                    ],
                    "status": "QUEUED",
                    "scheduledAt": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validação (instance_id, to, type, payload) ou envio para o próprio número (CANNOT_SEND_TO_SELF).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Bad Request",
                  "message": "Validation failed",
                  "details": [
                    {
                      "field": "payload.message",
                      "message": "text type requires payload.message"
                    }
                  ],
                  "code": "BAD_REQUEST"
                }
              }
            }
          },
          "401": {
            "description": "API Key ausente ou inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Trial/plano expirado (WORKSPACE_BLOCKED), créditos/saldo insuficientes (INSUFFICIENT_CREDITS / INSUFFICIENT_CREDITS_OR_BALANCE) ou limite da API Key (API_KEY_SPEND_LIMIT_EXCEEDED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo whatsapp:send ausente, acesso à instância negado ou agendamento não permitido (PLAN_LIMIT_SCHEDULING).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit excedido ou limite de warm-up da instância (WARMUP_DAILY_LIMIT: 20 msgs/dia nos primeiros 3 dias após firstConnectedAt).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Too Many Requests",
                  "code": "WARMUP_DAILY_LIMIT",
                  "message": "This instance is in the warm-up period (first 3 days). Daily send limit is 20. Try again tomorrow or wait until warm-up ends."
                }
              }
            }
          },
          "503": {
            "description": "Falha ao enfileirar mensagem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/inbound": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Listar recebidos WhatsApp",
        "description": "Mostra WhatsApp que chegaram — respostas ou mensagens de clientes.",
        "operationId": "ntfWa_getV1WhatsappMessagesInbound",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Busca no corpo ou no remetente (8+ dígitos)."
          },
          {
            "name": "instanceId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por instância (deve estar acessível pela chave)."
          },
          {
            "name": "dateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "dateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista e paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NtfWa_WhatsAppInboundListItem"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "inb_abc",
                      "from": "5511888888888",
                      "type": "TEXT",
                      "text": "Oi"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 20,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou instância não permitida para esta API Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/inbound/{id}": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Consultar recebido WhatsApp",
        "description": "Consulta os detalhes de uma mensagem recebida.",
        "operationId": "ntfWa_getV1WhatsappMessageInboundById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "clxxinbound001"
            },
            "description": "ID do inbound (mesmo valor de `inboundId` no webhook ou em GET /v1/whatsapp/messages/inbound)."
          }
        ],
        "responses": {
          "200": {
            "description": "Detalhe.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/NtfWa_WhatsAppInboundDetail"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "inb_abc",
                    "from": "5511888888888",
                    "type": "TEXT",
                    "text": "Oi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/inbound/{id}/media": {
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Baixar mídia recebida (base64)",
        "description": "Baixa foto, áudio ou documento de uma mensagem recebida. Retorno em base64 no JSON.",
        "operationId": "ntfWa_postV1WhatsappMessageInboundMedia",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "clxxinbound001"
            },
            "description": "ID do inbound (mesmo retornado em GET /v1/whatsapp/messages/inbound/{id}). Substitua `{id}` pelo valor real — sem ID a URL fica `/inbound//media`."
          }
        ],
        "responses": {
          "200": {
            "description": "Mídia baixada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/NtfWa_WhatsAppInboundMediaResponse"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "contentType": "audio/ogg; codecs=opus",
                    "fileName": "audio.ogg",
                    "base64": "T2dnUwACAAAAAAAAAAD//////////wEA..."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Mensagem sem mídia baixável ou instância indisponível.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Inbound não encontrado no workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Falha ao baixar mídia da conexão.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/inbound/{id}/media/download": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Baixar mídia recebida (arquivo)",
        "description": "Baixa a mídia como arquivo — ideal para salvar com curl ou scripts.",
        "operationId": "ntfWa_getV1WhatsappMessageInboundMediaDownload",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "clxxinbound001"
            },
            "description": "ID do inbound (mesmo inboundId do webhook ou de GET /v1/whatsapp/messages/inbound/inboundId)."
          }
        ],
        "responses": {
          "200": {
            "description": "Arquivo de mídia (image, audio ou document). Resposta binária (não JSON). Use `Content-Type` e `Content-Disposition` do header.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Mensagem sem mídia baixável ou instância indisponível.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Bad Request",
                  "message": "This inbound message has no downloadable media (image, audio, or document).",
                  "code": "INBOUND_MEDIA_NOT_FETCHABLE"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Forbidden",
                  "message": "This API key is not allowed to access this WhatsApp instance.",
                  "code": "INSTANCE_NOT_ALLOWED"
                }
              }
            }
          },
          "404": {
            "description": "Inbound não encontrado no workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Not Found",
                  "message": "Inbound message not found.",
                  "code": "NOT_FOUND"
                }
              }
            }
          },
          "502": {
            "description": "Falha ao baixar mídia da conexão.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Bad Gateway",
                  "message": "Failed to download media from WhatsApp connection.",
                  "code": "BAD_GATEWAY"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/presence": {
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Enviar presença no chat WhatsApp",
        "description": "Avisa que você está digitando ou gravando áudio em uma conversa.",
        "operationId": "ntfWa_postV1WhatsappMessagePresence",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "instanceId",
                  "to",
                  "presence"
                ],
                "properties": {
                  "instanceId": {
                    "type": "string",
                    "description": "ID da instância WhatsApp do workspace"
                  },
                  "to": {
                    "type": "string",
                    "description": "Telefone E.164 ou JID (@s.whatsapp.net / @g.us)"
                  },
                  "presence": {
                    "type": "string",
                    "enum": [
                      "composing",
                      "recording"
                    ],
                    "description": "composing = digitando; recording = gravando áudio"
                  },
                  "delayMs": {
                    "type": "integer",
                    "description": "Reservado para uso futuro; ignorado na v1"
                  }
                }
              },
              "example": {
                "instanceId": "inst_abc",
                "to": "5511999999999",
                "presence": "composing"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presença definida com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "instanceId": {
                          "type": "string"
                        },
                        "to": {
                          "type": "string"
                        },
                        "presence": {
                          "type": "string",
                          "enum": [
                            "composing",
                            "recording"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "ok": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Instância incompatível com presença ou payload inválido.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Falha ao enviar presença na conexão.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/{messageId}": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Consultar envio WhatsApp",
        "description": "Consulta se foi enviado, entregue ou falhou, e vê os detalhes.",
        "operationId": "ntfWa_getV1WhatsappMessage",
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dados da mensagem. Resposta padronizada com envelope success/data; status em MAIÚSCULO.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/NtfWa_WhatsAppMessageStatusResponse"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "msg_abc",
                    "instanceId": "inst_abc",
                    "status": "SENT",
                    "to": "5511999999999",
                    "type": "TEXT",
                    "createdAt": "2026-07-20T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Mensagem não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Apagar mensagem WhatsApp",
        "description": "Apaga uma mensagem que você enviou (quando o canal permite).",
        "operationId": "ntfWa_deleteV1WhatsappMessage",
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mensagem apagada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_MessageActionResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "messageId": "clxx...",
                    "status": "DELETED"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Sem external_id, já deletada, instância não conectada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Mensagem não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/{messageId}/edit": {
      "patch": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Editar mensagem WhatsApp",
        "description": "Edita o texto de uma mensagem já enviada (quando permitido).",
        "operationId": "ntfWa_patchV1WhatsappMessageEdit",
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "text"
                ],
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              },
              "example": {
                "message": "Texto corrigido"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem editada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_MessageActionResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "messageId": "clxx...",
                    "status": "EDITED"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Sem external_id, mensagem deletada, ou tipo não é text.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Mensagem não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/messages/{messageId}/cancel": {
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Cancelar WhatsApp agendado",
        "description": "Cancela algo que ainda não saiu — estava na fila ou agendado.",
        "operationId": "ntfWa_postV1WhatsappMessageCancel",
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mensagem cancelada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "messageId": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "CANCELLED"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "messageId": "clxx...",
                    "status": "CANCELLED"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Status PROCESSING (CANNOT_CANCEL_PROCESSING) ou não é QUEUED/SCHEDULED (CANNOT_CANCEL_STATUS).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Mensagem não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances": {
      "get": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Listar conexões WhatsApp",
        "description": "Lista as contas WhatsApp conectadas.",
        "operationId": "ntfWa_getV1WhatsappInstances",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "ACTIVE",
                "DISCONNECTED",
                "SUSPENDED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de instâncias e paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_InstanceListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "inst_abc",
                      "name": "Suporte",
                      "status": "ACTIVE",
                      "phoneNumber": "5511999999999",
                      "mode": "OFFICIAL",
                      "whatsappOfficialCloud": true,
                      "createdAt": "2026-07-20T12:00:00.000Z"
                    }
                  ],
                  "pagination": {
                    "total": 1,
                    "page": 1,
                    "limit": 20,
                    "totalPages": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo whatsapp:instances:list ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Criar instância WhatsApp",
        "description": "Conecta um número de WhatsApp ao seu workspace. Pense nisso como **cadastrar o telefone** que vai enviar e receber mensagens pelo Notifique.\n\nEscolha o exemplo que combina com o seu caso:\n\n- **Não oficial, QR na sua tela** — você mostra o código na sua interface e escaneia no celular.\n- **Não oficial, link para o cliente** — você envia um link; o cliente escaneia no WhatsApp dele.\n- **Oficial, link para o cliente** — você envia um link; o cliente faz login na Meta e vincula o número.\n- **Oficial, credenciais na hora** — você já concluiu o cadastro Meta no navegador e envia os dados nesta requisição.\n- **Oficial, token Meta próprio (BYOK)** — você usa token e IDs da sua conta Meta diretamente.\n\nEscopo: **whatsapp:instances:create**.",
        "operationId": "ntfWa_postV1WhatsappInstances",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 1024,
                    "description": "Nome para identificar este número no painel (ex.: Suporte, Vendas)."
                  },
                  "expectedPhoneNumber": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 20,
                    "description": "Opcional. Número internacional que você espera conectar (ex.: 5511999999999). Se escanear outro chip, a API responde 409."
                  },
                  "generateShareableLink": {
                    "type": "boolean",
                    "default": false,
                    "description": "Gera um **link** para outra pessoa concluir a conexão. Use `true` quando quem vai escanear ou fazer login Meta **não está na sua tela**. Omita ou use `false` para receber o QR direto na resposta e exibir na sua interface."
                  },
                  "metaEmbeddedCode": {
                    "type": "string",
                    "description": "Código retornado pelo Facebook ao concluir o cadastro Meta no navegador (Embedded Signup). Obrigatório na linha oficial, salvo quando usar link compartilhável."
                  },
                  "metaPhoneNumberId": {
                    "type": "string",
                    "description": "ID do número na Meta (linha oficial)."
                  },
                  "metaWabaId": {
                    "type": "string",
                    "description": "ID da conta WhatsApp Business na Meta (linha oficial)."
                  },
                  "metaBusinessId": {
                    "type": "string",
                    "description": "ID opcional do portfólio Business na Meta."
                  },
                  "metaPin": {
                    "type": "string",
                    "description": "PIN opcional de registro do número na Cloud API da Meta."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "UNOFFICIAL",
                      "OFFICIAL",
                      "OFFICIAL_BYOK",
                      "OFFICIAL_BSP"
                    ],
                    "description": "Tipo de conexão. **`UNOFFICIAL`** (padrão): QR no celular, ideal para testes. **`OFFICIAL`**: linha Meta (cadastro no navegador ou link para o cliente). **`OFFICIAL_BYOK`**: linha Meta com token e IDs que você já possui. **`OFFICIAL_BSP`**: reservado."
                  },
                  "metaAccessToken": {
                    "type": "string",
                    "description": "Token de acesso permanente da Meta (modo BYOK — credenciais próprias)."
                  }
                }
              },
              "examples": {
                "unofficialQrOnYourScreen": {
                  "summary": "Não oficial: QR na sua tela",
                  "description": "Você exibe o código na sua interface. Quem escaneia precisa estar com o celular na sua frente.",
                  "value": {
                    "name": "Suporte",
                    "mode": "UNOFFICIAL"
                  }
                },
                "unofficialLinkForCustomer": {
                  "summary": "Não oficial: link para o cliente escanear",
                  "description": "Envie o link para outra pessoa; ela abre e escaneia no WhatsApp dela.",
                  "value": {
                    "name": "Suporte",
                    "mode": "UNOFFICIAL",
                    "generateShareableLink": true
                  }
                },
                "officialLinkForCustomer": {
                  "summary": "Oficial: link para o cliente conectar na Meta",
                  "description": "O cliente abre o link e conclui o login Meta para vincular o número.",
                  "value": {
                    "name": "Suporte oficial",
                    "mode": "OFFICIAL",
                    "generateShareableLink": true
                  }
                },
                "officialWithMetaCredentials": {
                  "summary": "Oficial: credenciais Meta na hora",
                  "description": "Use quando o Embedded Signup já foi concluído no navegador.",
                  "value": {
                    "name": "Suporte oficial",
                    "mode": "OFFICIAL",
                    "metaEmbeddedCode": "CODE_DO_EMBEDDED_SIGNUP",
                    "metaPhoneNumberId": "123456789012345",
                    "metaWabaId": "987654321098765"
                  }
                },
                "officialByok": {
                  "summary": "Oficial: token Meta próprio (BYOK)",
                  "description": "Linha oficial com token e IDs da sua conta Meta.",
                  "value": {
                    "name": "Linha BYOK",
                    "mode": "OFFICIAL_BYOK",
                    "metaAccessToken": "EAAG...",
                    "metaPhoneNumberId": "123456789012345",
                    "metaWabaId": "987654321098765"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Número cadastrado. Se ainda falta conectar, a resposta traz o QR (`connection.base64`) ou um link (`shareableLink`) para concluir.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_CreateInstanceResponse"
                },
                "examples": {
                  "unofficialQrOnYourScreen": {
                    "summary": "Não oficial: aguardando scan do QR",
                    "value": {
                      "success": true,
                      "data": {
                        "instance": {
                          "id": "inst_abc",
                          "name": "Suporte",
                          "status": "PENDING",
                          "phoneNumber": null,
                          "mode": "UNOFFICIAL"
                        },
                        "connection": {
                          "status": "pending_qr",
                          "base64": "data:image/png;base64,...",
                          "code": "2@...",
                          "count": 1
                        }
                      }
                    }
                  },
                  "unofficialLinkForCustomer": {
                    "summary": "Não oficial: QR + link para o cliente",
                    "value": {
                      "success": true,
                      "data": {
                        "instance": {
                          "id": "inst_abc",
                          "name": "Suporte",
                          "status": "PENDING",
                          "phoneNumber": null,
                          "mode": "UNOFFICIAL"
                        },
                        "connection": {
                          "status": "pending_qr",
                          "base64": "data:image/png;base64,..."
                        },
                        "shareableLink": {
                          "hostedUrl": "https://api.notifique.dev/w/instance-connect/...?token=...",
                          "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/...?token=...",
                          "publicId": "..."
                        }
                      }
                    }
                  },
                  "officialLinkForCustomer": {
                    "summary": "Oficial: aguardando login Meta pelo cliente",
                    "value": {
                      "success": true,
                      "data": {
                        "instance": {
                          "id": "inst_abc",
                          "name": "Suporte oficial",
                          "status": "PENDING",
                          "phoneNumber": null,
                          "mode": "OFFICIAL",
                          "whatsappOfficialCloud": true
                        },
                        "connection": {
                          "status": "pending_signup"
                        },
                        "shareableLink": {
                          "hostedUrl": "https://api.notifique.dev/w/instance-connect/...?token=...",
                          "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/...?token=...",
                          "publicId": "..."
                        }
                      }
                    }
                  },
                  "officialActive": {
                    "summary": "Oficial: número já conectado",
                    "value": {
                      "success": true,
                      "data": {
                        "instance": {
                          "id": "inst_abc",
                          "name": "Suporte oficial",
                          "status": "ACTIVE",
                          "phoneNumber": "5511999999999",
                          "mode": "OFFICIAL"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou limite de instâncias (PLAN_LIMIT_INSTANCES).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro na conexão WhatsApp.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Capacidade global de instâncias cheia.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}": {
      "get": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Consultar conexão WhatsApp",
        "description": "Consulta os detalhes de uma conta WhatsApp conectada.",
        "operationId": "ntfWa_getV1WhatsappInstance",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dados da instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_InstanceResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "inst_abc",
                    "name": "Suporte",
                    "status": "ACTIVE",
                    "phoneNumber": "5511999999999",
                    "mode": "OFFICIAL",
                    "whatsappOfficialCloud": true,
                    "createdAt": "2026-07-20T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância negado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Remover conexão WhatsApp",
        "description": "Remove uma conta WhatsApp da sua configuração.",
        "operationId": "ntfWa_deleteV1WhatsappInstance",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Instância removida.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_InstanceActionResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "instanceId": "clxx...",
                    "status": "DELETED"
                  },
                  "message": "Instance removed. Logs and statistics are preserved."
                }
              }
            }
          },
          "400": {
            "description": "Instância ACTIVE; é necessário desconectar antes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Cannot delete active instance",
                  "message": "Disconnect the instance first, then delete it.",
                  "code": "INSTANCE_ACTIVE"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/connect-page": {
      "get": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Status do link WhatsApp",
        "description": "Consulta se o link para o cliente conectar está ativo.",
        "operationId": "ntfWa_getV1WhatsappInstanceConnectPage",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "inst_abc"
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração da página de conexão.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ConnectPageStatusResponse"
                },
                "examples": {
                  "disabled": {
                    "summary": "Link desabilitado",
                    "value": {
                      "success": true,
                      "data": {
                        "enabled": false,
                        "publicId": null,
                        "allowedHosts": [],
                        "needsSecretRotation": false,
                        "hostedUrl": null,
                        "embedUrl": null,
                        "iframeSnippet": null
                      }
                    }
                  },
                  "enabled": {
                    "summary": "Link habilitado com URLs",
                    "value": {
                      "success": true,
                      "data": {
                        "enabled": true,
                        "publicId": "V1StGXR8_Z5jdHi6B-myT",
                        "allowedHosts": [
                          "app.cliente.com"
                        ],
                        "needsSecretRotation": false,
                        "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                        "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                        "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>",
                        "shareableLink": {
                          "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                          "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                          "publicId": "V1StGXR8_Z5jdHi6B-myT",
                          "secret": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                          "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>"
                        }
                      }
                    }
                  },
                  "needsRotation": {
                    "summary": "Habilitado, mas precisa rotacionar o secret",
                    "value": {
                      "success": true,
                      "data": {
                        "enabled": true,
                        "publicId": "V1StGXR8_Z5jdHi6B-myT",
                        "allowedHosts": [],
                        "needsSecretRotation": true,
                        "hostedUrl": null,
                        "embedUrl": null,
                        "iframeSnippet": null,
                        "hostedUrlBase": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT",
                        "embedUrlBase": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Unauthorized",
                  "message": "Invalid or missing API Key",
                  "code": "UNAUTHORIZED"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou instância fora do escopo da API Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Forbidden",
                  "message": "Missing scope",
                  "code": "FORBIDDEN"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Not Found",
                  "message": "Instance not found",
                  "code": "NOT_FOUND"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/connect-page/enable": {
      "post": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Ativar link WhatsApp",
        "description": "Gera um link para outra pessoa concluir a conexão.",
        "operationId": "ntfWa_postV1WhatsappInstanceConnectPageEnable",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "inst_abc"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "allowedHosts": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Hosts permitidos para embed iframe (opcional).",
                    "example": [
                      "app.cliente.com",
                      "painel.cliente.com.br"
                    ]
                  }
                }
              },
              "examples": {
                "withHosts": {
                  "summary": "Com hosts permitidos para iframe",
                  "value": {
                    "allowedHosts": [
                      "app.cliente.com",
                      "painel.cliente.com.br"
                    ]
                  }
                },
                "empty": {
                  "summary": "Sem restrição de host",
                  "value": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Link habilitado (ou secret rotacionado).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ConnectPageEnableResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "publicId": "V1StGXR8_Z5jdHi6B-myT",
                    "secret": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>",
                    "shareableLink": {
                      "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "publicId": "V1StGXR8_Z5jdHi6B-myT",
                      "secret": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Unauthorized",
                  "message": "Invalid or missing API Key",
                  "code": "UNAUTHORIZED"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou instância fora do escopo da API Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Forbidden",
                  "message": "Missing scope",
                  "code": "FORBIDDEN"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Not Found",
                  "message": "Instance not found",
                  "code": "NOT_FOUND"
                }
              }
            }
          },
          "400": {
            "description": "Instância não elegível ou página não habilitada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Connect page is not enabled for this instance.",
                  "message": "Connect page is not enabled for this instance.",
                  "code": "CONNECT_PAGE_ERROR"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/connect-page/rotate-secret": {
      "post": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Renovar secret do link WhatsApp",
        "description": "Gera um novo secret de segurança para o link.",
        "operationId": "ntfWa_postV1WhatsappInstanceConnectPageRotate",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "inst_abc"
          }
        ],
        "responses": {
          "200": {
            "description": "Link habilitado (ou secret rotacionado).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ConnectPageEnableResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "publicId": "V1StGXR8_Z5jdHi6B-myT",
                    "secret": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                    "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>",
                    "shareableLink": {
                      "hostedUrl": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "embedUrl": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "publicId": "V1StGXR8_Z5jdHi6B-myT",
                      "secret": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
                      "iframeSnippet": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Unauthorized",
                  "message": "Invalid or missing API Key",
                  "code": "UNAUTHORIZED"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou instância fora do escopo da API Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Forbidden",
                  "message": "Missing scope",
                  "code": "FORBIDDEN"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Not Found",
                  "message": "Instance not found",
                  "code": "NOT_FOUND"
                }
              }
            }
          },
          "400": {
            "description": "Instância não elegível ou página não habilitada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Connect page is not enabled for this instance.",
                  "message": "Connect page is not enabled for this instance.",
                  "code": "CONNECT_PAGE_ERROR"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/connect-page/disable": {
      "post": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Desativar link WhatsApp",
        "description": "Desliga o link público de conexão.",
        "operationId": "ntfWa_postV1WhatsappInstanceConnectPageDisable",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "inst_abc"
          }
        ],
        "responses": {
          "200": {
            "description": "Link desabilitado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ConnectPageDisableResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "enabled": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Unauthorized",
                  "message": "Invalid or missing API Key",
                  "code": "UNAUTHORIZED"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ausente ou instância fora do escopo da API Key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Forbidden",
                  "message": "Missing scope",
                  "code": "FORBIDDEN"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Not Found",
                  "message": "Instance not found",
                  "code": "NOT_FOUND"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/qr": {
      "get": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Obter QR WhatsApp",
        "description": "Obtém o QR code para conectar WhatsApp no celular.",
        "operationId": "ntfWa_getV1WhatsappInstanceQr",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "QR atual (ou null se ACTIVE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "description": "PENDING, ACTIVE ou DISCONNECTED."
                        },
                        "base64": {
                          "type": "string",
                          "nullable": true,
                          "description": "Imagem do QR em base64 (data URL); null se instância ACTIVE."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "pending": {
                    "summary": "QR pendente",
                    "value": {
                      "success": true,
                      "data": {
                        "status": "PENDING",
                        "base64": "data:image/png;base64,...",
                        "loginUrl": null
                      }
                    }
                  },
                  "active": {
                    "summary": "Já conectado",
                    "value": {
                      "success": true,
                      "data": {
                        "status": "ACTIVE",
                        "base64": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Instância sem conexão WhatsApp configurada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Número conectado não corresponde ao vinculado ou expectedPhoneNumber (PHONE_NUMBER_MISMATCH).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": "Conflict",
                  "code": "PHONE_NUMBER_MISMATCH",
                  "message": "This number does not match the one originally linked to this instance. Create a new instance to use a different number."
                }
              }
            }
          },
          "429": {
            "description": "Cooldown de reconexão após desconexão involuntária ou excesso de tentativas (RECONNECT_COOLDOWN). Inclui retryAfterSec (segundos).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "retryAfterSec": {
                          "type": "integer",
                          "description": "Segundos até poder solicitar novo QR."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": false,
                  "error": "Too Many Requests",
                  "code": "RECONNECT_COOLDOWN",
                  "message": "Reconnection is temporarily blocked after an involuntary disconnect. Wait before requesting a new QR, or create a new instance if you need another number.",
                  "retryAfterSec": 21600
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/disconnect": {
      "post": {
        "tags": [
          "Instâncias"
        ],
        "summary": "Desconectar WhatsApp",
        "description": "Desconecta a sessão WhatsApp, mas mantém o cadastro.",
        "operationId": "ntfWa_postV1WhatsappInstanceDisconnect",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Instância desconectada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_InstanceActionResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "instanceId": "clxx...",
                    "status": "DISCONNECTED"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Instância sem conexão para desconectar.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo ou acesso à instância.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups": {
      "get": {
        "tags": [
          "Grupos"
        ],
        "summary": "Listar grupos WhatsApp",
        "description": "Lista os grupos desta conexão WhatsApp.",
        "operationId": "ntfWa_getV1WhatsappInstancesInstanceIdGroups",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID da instância no workspace."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Página da listagem (a partir de 1)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            },
            "description": "Quantidade por página (máx. 100)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de grupos (paginada) ou indicação de que a lista está sendo carregada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "loading": {
                      "type": "boolean",
                      "description": "Quando true, a lista ainda está sendo obtida; data virá vazio — tente novamente em alguns segundos."
                    },
                    "message": {
                      "type": "string",
                      "description": "Mensagem quando loading é true."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "JID do grupo (ex.: 120363295648424210@g.us)"
                          },
                          "name": {
                            "type": "string"
                          },
                          "participantsCount": {
                            "type": "integer"
                          },
                          "owner": {
                            "type": "string"
                          },
                          "creation": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "withData": {
                    "summary": "Sucesso — dados em cache (paginado)",
                    "value": {
                      "success": true,
                      "data": [
                        {
                          "id": "120363295648424210@g.us",
                          "name": "Meu Grupo",
                          "participantsCount": 5,
                          "owner": "5511999999999@s.whatsapp.net",
                          "creation": 1699000000
                        }
                      ],
                      "pagination": {
                        "page": 1,
                        "limit": 20,
                        "total": 5
                      }
                    }
                  },
                  "loading": {
                    "summary": "Carregando — tentar novamente em breve",
                    "value": {
                      "success": true,
                      "loading": true,
                      "message": "Lista de grupos está sendo carregada. Tente novamente em alguns segundos.",
                      "data": [],
                      "pagination": {
                        "page": 1,
                        "limit": 20,
                        "total": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "API Key ausente ou inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Escopo whatsapp:groups ausente ou instância oficial (WHATSAPP_GROUPS_UNOFFICIAL_ONLY).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups/{groupId}/participants": {
      "get": {
        "tags": [
          "Grupos"
        ],
        "summary": "Listar participantes do grupo",
        "description": "Mostra quem está no grupo.",
        "operationId": "ntfWa_getV1WhatsappInstancesInstanceIdGroupsGroupIdParticipants",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "JID do grupo (ex.: 120363295648424210@g.us) ou id numérico. Use encoding na URL para @ (ex.: 120363295648424210%40g.us)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de participantes do grupo.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "JID do participante (ex.: 5511999999999@s.whatsapp.net)"
                              },
                              "admin": {
                                "type": "string",
                                "description": "Papel no grupo (ex.: superadmin, admin)"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "participants": [
                      {
                        "id": "5511999999999@s.whatsapp.net",
                        "admin": "superadmin"
                      },
                      {
                        "id": "5511888888888@s.whatsapp.net",
                        "admin": "admin"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Recursos de grupos desativados ou escopo ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição (ex.: grupo não encontrado).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups/participants": {
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Atualizar participantes do grupo",
        "description": "Adiciona ou remove pessoas do grupo.",
        "operationId": "ntfWa_postV1WhatsappInstancesInstanceIdGroupsParticipants",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NtfWa_GroupParticipantsRequest"
              },
              "examples": {
                "single": {
                  "summary": "Um grupo",
                  "value": {
                    "to": [
                      "120363295648424210@g.us"
                    ],
                    "action": "add",
                    "participants": [
                      "5511999999999"
                    ]
                  }
                },
                "multiple": {
                  "summary": "Vários grupos",
                  "value": {
                    "to": [
                      "120363295648424210@g.us",
                      "120363295648424211@g.us"
                    ],
                    "action": "add",
                    "participants": [
                      "5511888888888",
                      "5511777777777"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "data.results: um item por grupo. Sucesso: groupJid, success: true, action, participantsCount. Falha: groupJid, success: false, error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "results": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "groupJid",
                              "success"
                            ],
                            "properties": {
                              "groupJid": {
                                "type": "string"
                              },
                              "success": {
                                "type": "boolean"
                              },
                              "action": {
                                "type": "string",
                                "enum": [
                                  "add",
                                  "remove"
                                ]
                              },
                              "participantsCount": {
                                "type": "integer"
                              },
                              "error": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "results": [
                      {
                        "groupJid": "120363295648424210@g.us",
                        "success": true,
                        "action": "add",
                        "participantsCount": 1
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "to (ou groupJid), action ou participants inválidos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Recursos de grupos desativados ou escopo ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Instância não vinculada (reconecte a instância).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups/invite": {
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Enviar convite de grupo",
        "description": "Envia um link para alguém entrar no grupo.",
        "operationId": "ntfWa_postV1WhatsappInstancesInstanceIdGroupsInvite",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NtfWa_GroupInviteSendRequest"
              },
              "examples": {
                "single": {
                  "summary": "Um grupo",
                  "value": {
                    "groups": [
                      "120363295648424210@g.us"
                    ],
                    "to": [
                      "5511999999999"
                    ],
                    "description": "Convite para o grupo"
                  }
                },
                "multiple": {
                  "summary": "Vários grupos",
                  "value": {
                    "groups": [
                      "120363295648424210@g.us",
                      "120363295648424211@g.us"
                    ],
                    "to": [
                      "5511999999999"
                    ],
                    "description": "Links dos grupos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "data.results: um item por grupo. Sucesso: groupJid, success: true, data.send, data.inviteUrl. Falha: groupJid, success: false, error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "results": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "groupJid": {
                                "type": "string"
                              },
                              "success": {
                                "type": "boolean"
                              },
                              "data": {
                                "type": "object",
                                "properties": {
                                  "send": {
                                    "type": "boolean"
                                  },
                                  "inviteUrl": {
                                    "type": "string"
                                  }
                                }
                              },
                              "error": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "results": [
                      {
                        "groupJid": "120363130091228687@g.us",
                        "success": true,
                        "data": {
                          "send": true,
                          "inviteUrl": "https://chat.whatsapp.com/EYkW0HWQLJ7CS82xdLIu4i"
                        }
                      },
                      {
                        "groupJid": "120363048720182344@g.us",
                        "success": true,
                        "data": {
                          "send": true,
                          "inviteUrl": "https://chat.whatsapp.com/Gst4H0uNCjMFEwddWjWpm9"
                        }
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "groups (ou groupJid) e to ausentes ou inválidos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Recursos de grupos desativados ou escopo ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups/invite/revoke": {
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Revogar convite de grupo",
        "description": "Invalida um link de convite ainda ativo.",
        "operationId": "ntfWa_postV1WhatsappInstancesInstanceIdGroupsInviteRevoke",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NtfWa_GroupInviteRevokeRequest"
              },
              "example": {
                "groupJid": "120363295648424210@g.us"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Link revogado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "revoked": {
                          "type": "boolean",
                          "example": true
                        },
                        "groupJid": {
                          "type": "string",
                          "example": "120363295648424210@g.us"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "revoked": true,
                    "groupJid": "120363295648424210@g.us"
                  }
                }
              }
            }
          },
          "400": {
            "description": "groupJid ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Recursos de grupos desativados ou escopo ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whatsapp/instances/{instanceId}/groups/invite-code": {
      "get": {
        "tags": [
          "Grupos"
        ],
        "summary": "Obter código de convite",
        "description": "Obtém o código ou link de convite do grupo.",
        "operationId": "ntfWa_getV1WhatsappInstancesInstanceIdGroupsInviteCode",
        "parameters": [
          {
            "name": "instanceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupJid",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "JID do grupo (ex.: 120363295648424210@g.us)"
          }
        ],
        "responses": {
          "200": {
            "description": "Código e URL de convite atual do grupo.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "inviteUrl": {
                          "type": "string",
                          "description": "URL completa do convite (https://chat.whatsapp.com/...)"
                        },
                        "inviteCode": {
                          "type": "string",
                          "description": "Código do convite (parte final da URL)"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "inviteUrl": "https://chat.whatsapp.com/Gst4H0uNCjMFEwddWjWpm9",
                    "inviteCode": "Gst4H0uNCjMFEwddWjWpm9"
                  }
                }
              }
            }
          },
          "400": {
            "description": "groupJid ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Não autorizado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Plano expirado ou suspenso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Recursos de grupos desativados ou escopo ausente.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Instância não encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Erro ao processar requisição.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NtfWa_ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ntfWaBearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "API Key no header Authorization. Exemplo: `Authorization: Bearer sk_live_xxxxx`"
      },
      "ntfWaApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API Key no header x-api-key."
      }
    },
    "schemas": {
      "NtfWa_ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "description": "Rótulo HTTP do erro (ex.: Unauthorized, Bad Request, Not Found)."
          },
          "message": {
            "type": "string",
            "description": "Mensagem legível para exibir ao usuário (localizada via Accept-Language / x-locale quando aplicável)."
          },
          "code": {
            "type": "string",
            "description": "Código estável da API v1 (enum). Sempre presente em erros. Use com o status HTTP para decidir retry ou correção. Ver [Respostas de erro](/guides/conceitos/resposta-de-erros)."
          },
          "details": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "error",
          "message",
          "code"
        ]
      },
      "NtfWa_WhatsAppInboundListItem": {
        "type": "object",
        "description": "Mensagem recebida; `receivedAt` em ISO 8601; sem payload bruto do conector nem IDs externos. `instance` identifica a conexão.",
        "properties": {
          "id": {
            "type": "string"
          },
          "instanceId": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "instance": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "phoneNumber": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "NtfWa_WhatsAppInboundDetail": {
        "type": "object",
        "description": "Detalhe do inbound: texto e metadados mínimos; sem payload bruto do conector.",
        "properties": {
          "id": {
            "type": "string"
          },
          "instanceId": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "contentPreview": {
            "type": "object",
            "description": "Prévia estruturada do conteúdo (kind, mimeType, fileName, durationSeconds, mediaUrl, etc.)."
          },
          "mediaFetch": {
            "type": "object",
            "nullable": true,
            "description": "Indica se a mídia pode ser baixada via POST /v1/whatsapp/messages/inbound/{id}/media ou GET /v1/whatsapp/messages/inbound/{id}/media/download.",
            "properties": {
              "fetchable": {
                "type": "boolean"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "image",
                  "audio",
                  "document"
                ]
              }
            }
          },
          "instance": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "phoneNumber": {
                "type": "string",
                "nullable": true
              }
            }
          }
        }
      },
      "NtfWa_WhatsAppInboundMediaResponse": {
        "type": "object",
        "description": "Arquivo de mídia do inbound em base64.",
        "properties": {
          "contentType": {
            "type": "string",
            "example": "audio/ogg; codecs=opus"
          },
          "fileName": {
            "type": "string",
            "nullable": true,
            "example": "audio.ogg"
          },
          "base64": {
            "type": "string",
            "description": "Conteúdo do arquivo codificado em base64 (sem prefixo data:)."
          }
        },
        "required": [
          "contentType",
          "base64"
        ]
      },
      "NtfWa_SendWhatsAppMessageRequest": {
        "type": "object",
        "required": [
          "instanceId",
          "to",
          "type",
          "payload"
        ],
        "properties": {
          "instanceId": {
            "type": "string",
            "description": "ID da instância WhatsApp do workspace."
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Destinatários: números com DDI (ex.: 5511999999999) ou JID de grupo (ex.: 120363295648424210@g.us). Uma mensagem por item."
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "audio",
              "document",
              "location",
              "contact",
              "buttons",
              "list"
            ],
            "description": "Tipo da mensagem. Templates oficiais Meta: use `POST /v1/templates/send` (não há `type: template` aqui)."
          },
          "payload": {
            "type": "object",
            "description": "Conteúdo conforme `type`. **text:** `message`. **image|video|audio|document:** `mediaUrl`, `fileName`, `mimetype` (obrigatórios); `caption` opcional. **location:** `latitude`, `longitude`, `name`, `address`. **contact:** `contact` ou `contactId`. **buttons:** `title`, `description`, `buttons` (1 a 3); `footer` opcional. **list:** `title`, `description`, `buttonText`, `listSections`; `footer` opcional.",
            "properties": {
              "message": {
                "type": "string",
                "maxLength": 1600,
                "description": "Obrigatório para type=text. Limite alinhado à validação da API (1600 caracteres)."
              },
              "mediaUrl": {
                "type": "string",
                "format": "uri",
                "description": "URL pública do arquivo. Obrigatório para image, video, audio, document."
              },
              "fileName": {
                "type": "string",
                "description": "Nome do arquivo. Obrigatório para mídia."
              },
              "mimetype": {
                "type": "string",
                "description": "Mimetype (ex.: image/jpeg, audio/mpeg, application/pdf). Obrigatório para mídia."
              },
              "caption": {
                "type": "string",
                "description": "Legenda opcional para image, video, audio ou document."
              },
              "latitude": {
                "type": "number",
                "description": "Obrigatório para type=location."
              },
              "longitude": {
                "type": "number",
                "description": "Obrigatório para type=location."
              },
              "name": {
                "type": "string",
                "description": "Nome do local. Obrigatório para type=location."
              },
              "address": {
                "type": "string",
                "description": "Endereço do local. Obrigatório para type=location."
              },
              "contact": {
                "type": "object",
                "description": "Objeto de contato. Requer fullName e pelo menos um de wuid ou phoneNumber. Opcionais: organization, email, url.",
                "properties": {
                  "fullName": {
                    "type": "string",
                    "description": "Nome completo do contato."
                  },
                  "wuid": {
                    "type": "string",
                    "description": "Número só dígitos com DDI (ex.: 5528999999999)."
                  },
                  "phoneNumber": {
                    "type": "string",
                    "description": "Número formatado (ex.: +55 28 99999-9999)."
                  },
                  "organization": {
                    "type": "string",
                    "description": "Empresa ou organização."
                  },
                  "email": {
                    "type": "string",
                    "description": "E-mail."
                  },
                  "url": {
                    "type": "string",
                    "description": "URL (site, etc.)."
                  }
                },
                "required": [
                  "fullName"
                ]
              },
              "contactId": {
                "type": "string",
                "description": "ID do contato do workspace. Alternativa a contact; o contato é resolvido no envio."
              },
              "vcard": {
                "type": "string",
                "description": "Deprecated. Use contact ou contact_id. vCard em string ainda aceito para compatibilidade."
              },
              "title": {
                "type": "string",
                "description": "Obrigatório para type=buttons ou type=list. Título (cabeçalho)."
              },
              "description": {
                "type": "string",
                "description": "Obrigatório para type=buttons ou type=list. Texto principal (corpo)."
              },
              "footer": {
                "type": "string",
                "description": "Opcional para type=buttons ou type=list. Rodapé (footerText enviado ao WhatsApp)."
              },
              "buttonText": {
                "type": "string",
                "maxLength": 20,
                "description": "Obrigatório para type=list. Texto do botão que abre a lista (máx. 20 caracteres na validação da API)."
              },
              "listSections": {
                "type": "array",
                "minItems": 1,
                "maxItems": 10,
                "description": "Obrigatório para type=list. Seções com linhas; no máximo 10 linhas no total entre todas as seções.",
                "items": {
                  "$ref": "#/components/schemas/NtfWa_WhatsAppListSection"
                }
              },
              "buttons": {
                "type": "array",
                "minItems": 1,
                "maxItems": 3,
                "description": "Obrigatório para type=buttons. Todos os botões devem ser do mesmo tipo: apenas reply, apenas url ou apenas call.",
                "items": {
                  "$ref": "#/components/schemas/NtfWa_WhatsAppButtonItem"
                }
              }
            }
          },
          "schedule": {
            "type": "object",
            "properties": {
              "sendAt": {
                "type": "string",
                "format": "date-time",
                "description": "Entre 5 minutos e 30 dias no futuro."
              }
            }
          },
          "options": {
            "type": "object",
            "properties": {
              "priority": {
                "type": "string",
                "enum": [
                  "high",
                  "normal",
                  "low"
                ],
                "default": "normal",
                "description": "`high` = fila prioritária de mensagens WhatsApp e fila prioritária de webhooks."
              },
              "maxRetries": {
                "type": "integer",
                "minimum": 0,
                "maximum": 5,
                "default": 3
              },
              "webhook": {
                "type": "object",
                "description": "Webhook só para este envio: eventos `message.*` destes destinatários vão para esta URL HTTPS.",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "secret": {
                    "type": "string",
                    "description": "Opcional. Segredo HMAC."
                  }
                }
              }
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Metadados por envio, mesclados em `Message.metadata` (pares string→string). Respeite limites de payload."
          }
        }
      },
      "NtfWa_WhatsAppListRow": {
        "type": "object",
        "required": [
          "rowId",
          "title"
        ],
        "properties": {
          "rowId": {
            "type": "string",
            "description": "Identificador único da linha em toda a mensagem (webhook ao selecionar)."
          },
          "title": {
            "type": "string",
            "maxLength": 24,
            "description": "Título da linha (máx. 24 na API)."
          },
          "description": {
            "type": "string",
            "maxLength": 72,
            "description": "Subtítulo opcional (máx. 72 na API)."
          }
        }
      },
      "NtfWa_WhatsAppListSection": {
        "type": "object",
        "required": [
          "title",
          "rows"
        ],
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 24,
            "description": "Título da seção (máx. 24 na API)."
          },
          "rows": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/NtfWa_WhatsAppListRow"
            }
          }
        }
      },
      "NtfWa_WhatsAppButtonReply": {
        "type": "object",
        "required": [
          "type",
          "displayText",
          "id"
        ],
        "description": "Botão de resposta. O `id` é referenciado quando o destinatário toca (eventos/webhooks).",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "reply"
            ]
          },
          "displayText": {
            "type": "string",
            "description": "Rótulo exibido no botão."
          },
          "id": {
            "type": "string",
            "description": "Identificador único do botão (payload do clique)."
          }
        }
      },
      "NtfWa_WhatsAppButtonUrl": {
        "type": "object",
        "required": [
          "type",
          "displayText",
          "url"
        ],
        "description": "Botão que abre URL. Deve ser HTTPS e host público (sem localhost/rede privada).",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "url"
            ]
          },
          "displayText": {
            "type": "string",
            "description": "Rótulo exibido no botão."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Link HTTPS público."
          }
        }
      },
      "NtfWa_WhatsAppButtonCall": {
        "type": "object",
        "required": [
          "type",
          "displayText",
          "phoneNumber"
        ],
        "description": "Botão que inicia ligação para o número informado (somente dígitos/DDI conforme validação da API).",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "call"
            ]
          },
          "displayText": {
            "type": "string",
            "description": "Rótulo exibido no botão."
          },
          "phoneNumber": {
            "type": "string",
            "description": "Número para discagem (ex.: 5511999999999)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "UNOFFICIAL",
              "OFFICIAL",
              "OFFICIAL_BYOK",
              "OFFICIAL_BSP"
            ],
            "description": "Modo público de conexão."
          }
        }
      },
      "NtfWa_WhatsAppButtonItem": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/NtfWa_WhatsAppButtonReply"
          },
          {
            "$ref": "#/components/schemas/NtfWa_WhatsAppButtonUrl"
          },
          {
            "$ref": "#/components/schemas/NtfWa_WhatsAppButtonCall"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "reply": "#/components/schemas/NtfWa_WhatsAppButtonReply",
            "url": "#/components/schemas/NtfWa_WhatsAppButtonUrl",
            "call": "#/components/schemas/NtfWa_WhatsAppButtonCall"
          }
        }
      },
      "NtfWa_SendWhatsAppMessageResponse": {
        "type": "object",
        "description": "Conteúdo de data na resposta de envio.",
        "properties": {
          "messageIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "IDs das mensagens criadas."
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "SCHEDULED"
            ],
            "description": "Status em MAIÚSCULO."
          },
          "scheduledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Presente quando status é SCHEDULED."
          }
        }
      },
      "NtfWa_WhatsAppMessageStatusResponse": {
        "type": "object",
        "description": "Conteúdo de data na resposta de status. Status sempre em MAIÚSCULO.",
        "properties": {
          "messageId": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Sempre em MAIÚSCULO (ex.: QUEUED, SENT, DELIVERED, READ, FAILED)."
          },
          "scheduledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "deliveredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "readAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "failedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "errorMessage": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NtfWa_MessageActionResponse": {
        "type": "object",
        "description": "Resposta padronizada para cancel, delete e edit: envelope success/data; data contém message_id e status em MAIÚSCULO.",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "messageId": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "CANCELLED",
                  "DELETED",
                  "EDITED"
                ]
              }
            }
          }
        }
      },
      "NtfWa_InstanceListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "phoneNumber": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "PENDING",
                    "ACTIVE",
                    "DISCONNECTED",
                    "SUSPENDED",
                    "CANCELLED"
                  ]
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "page": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "totalPages": {
                "type": "integer"
              }
            }
          }
        }
      },
      "NtfWa_InstanceResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "phoneNumber": {
                "type": "string",
                "nullable": true
              },
              "expectedPhoneNumber": {
                "type": "string",
                "nullable": true,
                "description": "Número esperado informado na criação (conexão não oficial)."
              },
              "lockedPhoneNumber": {
                "type": "string",
                "nullable": true,
                "description": "Número permanentemente vinculado após o primeiro pareamento (conexão não oficial)."
              },
              "reconnectBlockedUntil": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Até quando a reconexão fica bloqueada após desconexão involuntária."
              },
              "firstConnectedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Data/hora da primeira conexão bem-sucedida (base do warm-up)."
              },
              "warmup": {
                "$ref": "#/components/schemas/NtfWa_WarmupSnapshot"
              },
              "status": {
                "type": "string"
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        }
      },
      "NtfWa_CreateInstanceResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "instance": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "phoneNumber": {
                    "type": "string",
                    "nullable": true
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "UNOFFICIAL",
                      "OFFICIAL",
                      "OFFICIAL_BYOK",
                      "OFFICIAL_BSP"
                    ]
                  }
                }
              },
              "connection": {
                "type": "object",
                "description": "Dados para pareamento: QR em base64, code, pairingCode e count (UNOFFICIAL); ou status do provider oficial (OFFICIAL*).",
                "properties": {
                  "pairingCode": {
                    "type": "string",
                    "nullable": true,
                    "description": "Código de pareamento (quando disponível)."
                  },
                  "code": {
                    "type": "string",
                    "description": "Código interno de conexão."
                  },
                  "base64": {
                    "type": "string",
                    "description": "Imagem do QR code em Data URL (ex.: data:image/png;base64,...). Use para exibir o QR (ex.: <img src=\"connection.base64\" />)."
                  },
                  "count": {
                    "type": "integer",
                    "description": "Contador do QR/geração."
                  }
                },
                "example": {
                  "pairingCode": null,
                  "code": "2@KbXFfHsvo+byvkP6k4VoBIE5gZFwYHT9y6dNt/c6Sfg6M+...",
                  "base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVwAAAFcCAYAAACEFgYs...",
                  "count": 1
                }
              },
              "shareableLink": {
                "$ref": "#/components/schemas/NtfWa_ShareableLink"
              }
            }
          }
        }
      },
      "NtfWa_InstanceActionResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "instanceId": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "message": {
            "type": "string"
          }
        }
      },
      "NtfWa_WarmupSnapshot": {
        "type": "object",
        "description": "Estado do warm-up da instância (conexão não oficial, primeiros 3 dias após firstConnectedAt).",
        "properties": {
          "active": {
            "type": "boolean",
            "description": "Se a instância está em warm-up."
          },
          "dailyLimit": {
            "type": "integer",
            "description": "Limite diário de envios durante warm-up (20)."
          },
          "sentToday": {
            "type": "integer",
            "description": "Envios já contabilizados hoje (UTC)."
          },
          "daysRemaining": {
            "type": "integer",
            "description": "Dias restantes na janela de warm-up."
          }
        }
      },
      "NtfWa_GroupParticipantsRequest": {
        "type": "object",
        "required": [
          "action",
          "participants"
        ],
        "properties": {
          "to": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^\\d+@g\\.us$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "JIDs dos grupos (ex.: 120363295648424210@g.us). Obrigatório se groupJid não for enviado."
          },
          "groupJid": {
            "type": "string",
            "description": "Deprecated. Use to. JID de um único grupo; equivale a to: [groupJid]."
          },
          "action": {
            "type": "string",
            "enum": [
              "add",
              "remove"
            ]
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "description": "Números com DDI ou JIDs (ex.: 5511999999999)"
          }
        }
      },
      "NtfWa_GroupInviteSendRequest": {
        "type": "object",
        "required": [
          "to"
        ],
        "properties": {
          "groups": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^\\d+@g\\.us$"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "JIDs dos grupos cujo link será enviado. Um ou mais."
          },
          "groupJid": {
            "type": "string",
            "description": "Deprecated. Use groups. JID de um único grupo."
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "description": "Números com DDI que receberão os links (ex.: 5511999999999)"
          },
          "description": {
            "type": "string",
            "description": "Texto enviado com o convite (opcional)"
          }
        }
      },
      "NtfWa_GroupInviteRevokeRequest": {
        "type": "object",
        "required": [
          "groupJid"
        ],
        "properties": {
          "groupJid": {
            "type": "string",
            "description": "JID do grupo (ex.: 120363295648424210@g.us)"
          }
        }
      },
      "NtfWa_ShareableLink": {
        "type": "object",
        "description": "URLs da página pública de conexão. Quem tiver a URL pode conectar/desconectar a instância — rotacione o secret após o uso.",
        "properties": {
          "hostedUrl": {
            "type": "string",
            "description": "URL hospedada da página de conexão (inclui o token).",
            "example": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345"
          },
          "embedUrl": {
            "type": "string",
            "description": "URL para embed em iframe (inclui o token).",
            "example": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345"
          },
          "publicId": {
            "type": "string",
            "description": "ID público da página de conexão.",
            "example": "V1StGXR8_Z5jdHi6B-myT"
          },
          "secret": {
            "type": "string",
            "description": "Secret bruto (retornado em enable/rotate). Prefira usar hostedUrl, que já embute o token.",
            "example": "AbCdEfGhIjKlMnOpQrStUvWxYz012345"
          },
          "iframeSnippet": {
            "type": "string",
            "description": "Snippet HTML de iframe pronto para colar.",
            "example": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>"
          }
        },
        "required": [
          "hostedUrl",
          "embedUrl",
          "publicId"
        ]
      },
      "NtfWa_ConnectPageStatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "example": true
              },
              "publicId": {
                "type": "string",
                "nullable": true,
                "example": "V1StGXR8_Z5jdHi6B-myT"
              },
              "allowedHosts": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [
                  "app.cliente.com"
                ]
              },
              "needsSecretRotation": {
                "type": "boolean",
                "description": "true quando o secret não está mais disponível no servidor — chame rotate-secret para obter novas URLs.",
                "example": false
              },
              "hostedUrl": {
                "type": "string",
                "nullable": true,
                "example": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345"
              },
              "embedUrl": {
                "type": "string",
                "nullable": true,
                "example": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345"
              },
              "iframeSnippet": {
                "type": "string",
                "nullable": true,
                "example": "<iframe src=\"https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT?token=AbCdEfGhIjKlMnOpQrStUvWxYz012345\" style=\"border:0;width:100%;min-height:560px\" allow=\"clipboard-read; clipboard-write\"></iframe>"
              },
              "secret": {
                "type": "string",
                "nullable": true,
                "description": "Presente no GET quando o secret ainda está disponível no servidor.",
                "example": "AbCdEfGhIjKlMnOpQrStUvWxYz012345"
              },
              "hostedUrlBase": {
                "type": "string",
                "nullable": true,
                "description": "Base da URL hospedada sem token (quando needsSecretRotation=true).",
                "example": "https://api.notifique.dev/w/instance-connect/V1StGXR8_Z5jdHi6B-myT"
              },
              "embedUrlBase": {
                "type": "string",
                "nullable": true,
                "description": "Base da URL de embed sem token (quando needsSecretRotation=true).",
                "example": "https://api.notifique.dev/w/embed/instance-connect/V1StGXR8_Z5jdHi6B-myT"
              },
              "shareableLink": {
                "$ref": "#/components/schemas/NtfWa_ShareableLink"
              }
            }
          }
        }
      },
      "NtfWa_ConnectPageEnableResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NtfWa_ShareableLink"
              },
              {
                "type": "object",
                "properties": {
                  "shareableLink": {
                    "$ref": "#/components/schemas/NtfWa_ShareableLink"
                  }
                }
              }
            ]
          }
        }
      },
      "NtfWa_ConnectPageDisableResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "example": false
              }
            },
            "required": [
              "enabled"
            ]
          }
        }
      }
    }
  }
}
