{
  "openapi": "3.0.3",
  "info": {
    "title": "ViperConnect API",
    "version": "2.5.2",
    "description": "API para integração com WhatsApp, sessões, mensagens, contatos, grupos, mídia, webhooks e operações administrativas. Rotas compatíveis usam `/{version}` e aceitam prefixos como `v15`, `v22` ou `v25`."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [
    {
      "ApiToken": []
    }
  ],
  "paths": {
    "/{version}/{phone}/conversations": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "operationId": "getVersionPhoneConversations",
        "summary": "Listar conversas do histórico local da sessão",
        "description": "Zapo/Redis apenas. Token global, da sessão ou Manager autorizado. Sem consulta ao WhatsApp, recibo de leitura ou renovação do TTL. Inicialização do índice em background (indexing=true). Busca examina até 200 resumos por página; página vazia pode ter continuação. Não retorna contagem global. Exclui Status/newsletters.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "default": "v15.0"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Cursor opaco vinculado à sessão/filtros"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 100
            },
            "description": "Nome/telefone/identidade; não conteúdo"
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "direct",
                "group"
              ],
              "default": "all"
            }
          },
          {
            "name": "conversation_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Até 100 JIDs separados por vírgula para atualizar somente resumos afetados"
          }
        ],
        "responses": {
          "200": {
            "description": "Página de resumos locais",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "has_more",
                    "next_cursor",
                    "indexing"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionConversation"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    },
                    "indexing": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Filtro/cursor inválido"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Acesso à sessão negado"
          },
          "409": {
            "description": "Zapo/Redis indisponível ou cursor expirado/movido; recarregar primeira página"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/:version/:phone/conversations"
      }
    },
    "/{version}/{phone}/conversations/{conversationId}/messages": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "operationId": "getVersionPhoneConversationsConversationIdMessages",
        "summary": "Histórico local paginado, sem marcar como lido",
        "description": "Ordem decrescente timestamp/ID, preservando empates. Cursor ancorado no ID, sem deslocamento por novas mensagens. Retenção Redis pela data original (padrão 30 dias), sem renovação por leitura, regravação ou sincronização. Sem data válida, janela fixa desde a primeira gravação. Dados antigos não tocados aguardam o TTL anterior; mensagens com data expirada não são retornadas. Sem protobuf, URLs CDN ou chaves de mídia. Edições/remoções quando recebidas geram overlays locais. Reutilize POST messages para envio/resposta, com reply_id em context.message_id. Políticas existentes readOnReceipt/readOnReply são independentes.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "default": "v15.0"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "JID @lid, @s.whatsapp.net ou @g.us; URL-encode"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Até 100 IDs de provider separados por vírgula para delta dentro da conversa"
          },
          {
            "name": "status_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Até 100 IDs UnoAPI separados por vírgula para recuperar status pendente após reconexão"
          },
          {
            "name": "around",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ID de provider para carregar uma janela limitada ao redor da mensagem citada; não combinar com cursor ou ids. Retorna 404 quando expirada ou fora da conversa."
          }
        ],
        "responses": {
          "200": {
            "description": "Página de projeções públicas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "has_more",
                    "next_cursor"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionConversationMessage"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    },
                    "statuses": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "error": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "JID",
            "IDs ou cursor inválidos": null
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Sessão fora do escopo"
          },
          "404": {
            "description": "Mensagem original indisponível no histórico da conversa"
          },
          "409": {
            "description": "Zapo/Redis indisponível ou cursor expirado; recarregar"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/:version/:phone/conversations/:conversationId/messages"
      }
    },
    "/{version}/{phone}/messages/{messageId}/media": {
      "get": {
        "tags": [
          "Mensagens"
        ],
        "operationId": "getVersionPhoneMessagesMessageIdMedia",
        "summary": "Carregar mídia autorizada sob demanda",
        "description": "Consulta a mensagem na sessão antes de acessar storage. Reutiliza mídia interna; quando ausente, download/decrypt oficial Zapo sem abrir socket WhatsApp, respeitando proxy/família IP. Máximo 256 MiB/60s; concorrência deduplicada por processo. Mídia expirada pode falhar; nunca expõe view_once ou mídia removida. Sem predownload/reupload automático. Cache-Control no-store, attachment e nosniff.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "default": "v15.0"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID de provider devolvido na listagem"
          }
        ],
        "responses": {
          "200": {
            "description": "Bytes da mídia",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "ID inválido"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Sessão proibida ou mídia view_once/removida"
          },
          "404": {
            "description": "Mensagem expirada/ausente ou sem mídia"
          },
          "409": {
            "description": "Store não Zapo/Redis"
          },
          "502": {
            "description": "Falha no stream do storage"
          },
          "503": {
            "description": "Falha de download/decrypt ou Redis"
          }
        },
        "x-source-route": "/:version/:phone/messages/:messageId/media"
      }
    },
    "/{phone}/profile/privacy": {
      "get": {
        "tags": [
          "Perfil"
        ],
        "operationId": "getPhoneProfilePrivacy",
        "summary": "Consultar privacidade da própria conta",
        "description": "Sessões Zapo vinculadas e mobile primary. Consulta o worker; snapshot Redis por sessão, TTL 24h, como fallback de falhas totais/parciais. Sem polling. Cache não inclui Status/e-mail; erros de autorização não usam fallback. Escritas invalidam snapshot e impedem gravação de leituras anteriores. Ausência não significa vazio. Exige autenticação e escopo da sessão.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Configurações disponíveis e falhas parciais",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "settings": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Valores por configuração conforme PrivacyInput; categorias indisponíveis são omitidas."
                    },
                    "cache": {
                      "type": "object",
                      "properties": {
                        "source": {
                          "type": "string",
                          "enum": [
                            "live",
                            "cache",
                            "mixed"
                          ]
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "stale": {
                          "type": "boolean"
                        },
                        "refresh_failed": {
                          "type": "boolean"
                        }
                      }
                    },
                    "blocked": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "string"
                      }
                    },
                    "duration": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Duração consultada em segundos; null indica ausência de resultado"
                    },
                    "exceptions": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "settings, blocked, timer ou exceptions.NOME cuja consulta falhou"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Telefone ou entrada inválida"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo"
          },
          "409": {
            "description": "Sessão desconectada"
          },
          "501": {
            "description": "Capacidade indisponível"
          },
          "502": {
            "description": "Falha no transporte ou provedor"
          }
        }
      },
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfilePrivacy",
        "summary": "Alterar uma configuração, exceções, bloqueio ou duração padrão",
        "description": "Alterações independentes, sem transação global. Exceções são deltas e ativam contact_blacklist. Timer afeta novas conversas individuais. Status substitui o público/lista dos próximos Status; não há leitura desse público nesta rota. Não repetir automaticamente após falha de transporte. Mesmo controle de escopo do perfil.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "$ref": "#/components/schemas/PrivacyInput"
                  }
                }
              },
              "examples": {
                "visibility": {
                  "value": {
                    "value": {
                      "operation": "setting",
                      "setting": "lastSeen",
                      "value": "contacts"
                    }
                  }
                },
                "exceptions": {
                  "value": {
                    "value": {
                      "operation": "exceptions",
                      "setting": "lastSeen",
                      "add": [
                        "5511999999999"
                      ],
                      "remove": []
                    }
                  }
                },
                "block": {
                  "value": {
                    "value": {
                      "operation": "block",
                      "jid": "5511999999999"
                    }
                  }
                },
                "unblock": {
                  "value": {
                    "value": {
                      "operation": "unblock",
                      "jid": "123456789@lid"
                    }
                  }
                },
                "timer": {
                  "value": {
                    "value": {
                      "operation": "timer",
                      "duration": 604800
                    }
                  }
                },
                "status": {
                  "value": {
                    "value": {
                      "operation": "status",
                      "mode": "ALLOW_LIST",
                      "userJids": [
                        "5511999999999"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrita confirmada pelo SDK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Operação ou valor inválido para a configuração"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo"
          },
          "409": {
            "description": "Sessão desconectada"
          },
          "501": {
            "description": "Capacidade indisponível"
          },
          "502": {
            "description": "Falha ao alterar; consultar antes de repetir. Não prova que a alteração remota não ocorreu."
          }
        }
      }
    },
    "/{phone}/profile/account_email": {
      "get": {
        "tags": [
          "Perfil"
        ],
        "operationId": "getPhoneProfileAccountEmail",
        "summary": "Consultar e-mail da conta WhatsApp (mobile primary)",
        "description": "Consulta direta sem cache Redis, com Cache-Control no-store. Usa autenticação e escopo da sessão; indisponível em sessão vinculada. Não é o e-mail comercial público.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Estado atual",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountEmailStatus"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação proibida"
          },
          "409": {
            "description": "Sessão desconectada ou não mobile primary"
          },
          "502": {
            "description": "Falha de consulta no provedor"
          }
        }
      },
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileAccountEmail",
        "summary": "Cadastrar ou verificar e-mail da conta (mobile primary)",
        "description": "Ações explícitas e separadas: set cadastra; request_code solicita código pt-BR; verify valida seis dígitos; confirm confirma a propriedade após verificação. Não envia código automaticamente, não remove e-mail e não altera o e-mail comercial. Código não entra no cache de perfil. Falha de transporte pode ter resultado incerto: consultar antes de repetir.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "oneOf": [
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "operation",
                          "email"
                        ],
                        "properties": {
                          "operation": {
                            "type": "string",
                            "enum": [
                              "set"
                            ]
                          },
                          "email": {
                            "type": "string",
                            "format": "email",
                            "maxLength": 320
                          }
                        }
                      },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "operation",
                          "code"
                        ],
                        "properties": {
                          "operation": {
                            "type": "string",
                            "enum": [
                              "verify"
                            ]
                          },
                          "code": {
                            "type": "string",
                            "pattern": "^[0-9]{6}$",
                            "writeOnly": true
                          }
                        }
                      },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "operation"
                        ],
                        "properties": {
                          "operation": {
                            "type": "string",
                            "enum": [
                              "request_code",
                              "confirm"
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              },
              "examples": {
                "set": {
                  "value": {
                    "value": {
                      "operation": "set",
                      "email": "conta@example.com"
                    }
                  }
                },
                "request_code": {
                  "value": {
                    "value": {
                      "operation": "request_code"
                    }
                  }
                },
                "verify": {
                  "value": {
                    "value": {
                      "operation": "verify",
                      "code": "123456"
                    }
                  }
                },
                "confirm": {
                  "value": {
                    "value": {
                      "operation": "confirm"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação confirmada pelo SDK; verify não executa confirm automaticamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "email": {
                      "type": "string",
                      "nullable": true
                    },
                    "verified": {
                      "type": "boolean"
                    },
                    "confirmed": {
                      "type": "boolean"
                    },
                    "auto_verify_failed": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida ou código incorreto/expirado"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Fora do escopo ou operação proibida"
          },
          "409": {
            "description": "Offline",
            "não mobile primary": null,
            "e-mail ausente ou não verificado": null
          },
          "429": {
            "description": "Bloqueio temporário ou excesso de tentativas; não repetir automaticamente"
          },
          "502": {
            "description": "Falha de provedor; consultar situação antes de repetir"
          }
        }
      }
    },
    "/admin/settings/google-maps/browser": {
      "get": {
        "tags": [
          "Administração"
        ],
        "operationId": "getAdminSettingsGoogleMapsBrowser",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "summary": "Obter chave de navegador para Google Maps (administrador)",
        "description": "Somente administrador. Retorna chave restrita a referrers para Maps JavaScript API, com Cache-Control no-store. A chave será visível no navegador; nunca usar chave irrestrita de servidor.",
        "responses": {
          "200": {
            "description": "Configuração do navegador",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "apiKey": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/admin/settings/google-maps/browser",
        "parameters": []
      }
    },
    "/admin/settings/google-maps": {
      "get": {
        "tags": [
          "Administração"
        ],
        "operationId": "getAdminSettingsGoogleMaps",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "summary": "Consultar configuração Google Maps (administrador)",
        "description": "Estado global da instância; não retorna a chave. Mapa disponível ao administrador no perfil comercial, com carregamento explícito.",
        "responses": {
          "200": {
            "description": "Estado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configured": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/admin/settings/google-maps",
        "parameters": []
      },
      "put": {
        "tags": [
          "Administração"
        ],
        "operationId": "putAdminSettingsGoogleMaps",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "summary": "Salvar chave de navegador Google Maps (administrador)",
        "description": "Redis sem TTL e sem criptografia adicional. Restrinja domínios e APIs no Google Cloud. Não verifica validade ou quota e nunca retorna a chave.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "apiKey"
                ],
                "properties": {
                  "apiKey": {
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200,
                    "writeOnly": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chave salva; configured true"
          },
          "400": {
            "description": "Corpo inválido"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/admin/settings/google-maps",
        "parameters": []
      },
      "delete": {
        "tags": [
          "Administração"
        ],
        "operationId": "deleteAdminSettingsGoogleMaps",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "summary": "Remover chave Google Maps (administrador)",
        "description": "Remove a configuração global compartilhada entre as sessões.",
        "responses": {
          "200": {
            "description": "Chave removida; configured false"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "503": {
            "description": "Redis indisponível"
          }
        },
        "x-source-route": "/admin/settings/google-maps",
        "parameters": []
      }
    },
    "/{phone}/profile": {
      "get": {
        "tags": [
          "Perfil"
        ],
        "operationId": "getPhoneProfile",
        "summary": "Consultar o perfil da própria sessão Zapo",
        "description": "Funciona com sessões vinculadas e mobile primary, pessoais e Business. Campos de leitura indisponíveis ficam nulos e são listados em warnings; não são campos apagados. Não retorna credenciais nem PIN de username. Somente a sessão autenticada, sem parâmetro de JID alvo.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "name": "refresh",
            "in": "query",
            "description": "Use 1 para consultar a Zapo e renovar o cache. Sem esse parâmetro, retorna Redis quando disponível; cache ausente consulta a Zapo. Falhas preservam snapshot anterior e sinalizam stale/refresh_failed. Retenção de 24h.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Perfil e avisos de leituras parciais",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfile"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo"
          },
          "409": {
            "description": "Sessão desconectada"
          },
          "501": {
            "description": "Motor sem suporte"
          },
          "502": {
            "description": "Falha no provedor"
          }
        },
        "x-source-route": "/:phone/profile",
        "x-source-controller": "ownProfileController.handle"
      }
    },
    "/{phone}/profile/name": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileName",
        "summary": "Alterar nome de exibição",
        "description": "pushName; não modifica o nome comercial verificado. String vazia restaura o padrão do dispositivo.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "maxLength": 128
                  }
                }
              },
              "example": {
                "value": "João Silva"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/{phone}/profile/about": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileAbout",
        "summary": "Alterar recado About",
        "description": "Recado legado via setStatus, não Status de 24 horas. String vazia limpa.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "maxLength": 139
                  }
                }
              },
              "example": {
                "value": "Atendimento de segunda a sexta"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/{phone}/profile/username": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileUsername",
        "summary": "Alterar nome de usuário",
        "description": "Sujeito às regras adicionais da Zapo e disponibilidade no servidor. Retorno false do SDK resulta em 409, não sucesso.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 35,
                    "pattern": "^[a-zA-Z0-9_.]+$"
                  }
                }
              },
              "example": {
                "value": "empresa_suporte"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      },
      "delete": {
        "tags": [
          "Perfil"
        ],
        "operationId": "deletePhoneProfileUsername",
        "summary": "Remover username da própria sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/{phone}/profile/business": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileBusiness",
        "summary": "Atualizar dados comerciais",
        "description": "Exclusivo de conta Business, independentemente do tipo de conexão. Delta: campos omitidos preservados, string vazia limpa, listas vazias limpam. Não edita nome verificado, área de cobertura nem observações de localização. IDs de categoria devem ser conhecidos; sem catálogo.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "$ref": "#/components/schemas/OwnBusinessInput"
                  }
                }
              },
              "example": {
                "value": {
                  "description": "Suporte de TI",
                  "address": "Cláudia - MT",
                  "latitude": -11.499317,
                  "longitude": -54.873917,
                  "websites": [
                    {
                      "url": "https://example.com"
                    }
                  ],
                  "businessHours": {
                    "timezone": "America/Cuiaba",
                    "config": [
                      {
                        "dayOfWeek": "mon",
                        "mode": "specific_hours",
                        "openTime": 480,
                        "closeTime": 1080
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/{phone}/profile/picture": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfilePicture",
        "summary": "Enviar foto de perfil",
        "description": "Até 5 MiB de bytes decodificados, máximo 20 milhões de pixels. PNG/JPEG/WebP são decodificados, orientação corrigida, recorte central 640x640 e JPEG. Sem URLs remotas nem JID alvo.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "format": "byte",
                    "maxLength": 7000000
                  }
                }
              },
              "example": {
                "value": "BASE64_DA_IMAGEM_SEM_PREFIXO_DATA"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      },
      "delete": {
        "tags": [
          "Perfil"
        ],
        "operationId": "deletePhoneProfilePicture",
        "summary": "Remover foto da própria sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/{phone}/profile/cover": {
      "put": {
        "tags": [
          "Perfil"
        ],
        "operationId": "putPhoneProfileCover",
        "summary": "Enviar capa Business",
        "description": "Business somente; exige S3 configurado. Até 5 MiB, 20 milhões de pixels; JPEG com largura máxima 1600, sem recorte quadrado. Persiste imagem no S3 e ID no Redis sem TTL. GET profile retorna preview local com URL assinada por 15 minutos. O SDK não oferece leitura da capa remota; alterações externas não são detectadas. Falhas de persistência após confirmação remota retornam success e warning; guarde o ID nesse caso.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "format": "byte",
                    "maxLength": 7000000
                  }
                }
              },
              "example": {
                "value": "BASE64_DA_IMAGEM_SEM_PREFIXO_DATA"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      },
      "delete": {
        "tags": [
          "Perfil"
        ],
        "operationId": "deletePhoneProfileCover",
        "summary": "Remover capa comercial pelo ID retornado no envio",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "maxLength": 128,
                    "pattern": "^[\\w-]+$"
                  }
                }
              },
              "example": {
                "value": "ID_RETORNADO_AO_ENVIAR_CAPA"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmado pelo SDK; não é garantia de propagação imediata aos demais dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnProfileMutation"
                }
              }
            }
          },
          "400": {
            "description": "Campo ou valor inválido"
          },
          "401": {
            "description": "Autenticação necessária"
          },
          "403": {
            "description": "Sessão fora do escopo ou operação recusada"
          },
          "409": {
            "description": "Sessão offline",
            "conta não Business ou username recusado": null
          },
          "501": {
            "description": "Motor não suporta edição de perfil"
          },
          "502": {
            "description": "Falha no provedor; consultar perfil antes de repetir uma escrita de resultado incerto"
          }
        }
      }
    },
    "/manager/mobile-devices/{id}/companion-history": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Envio manual de histórico desabilitado",
        "deprecated": true,
        "description": "Retorna 410 mobile_history_pair_time_only. O histórico agora é iniciado automaticamente no bootstrap de um novo vínculo, não depois nem em reconexões. Fila separada; todo o histórico elegível disponível no Redis, sem corte por idade ou quantidade total, lido em páginas de 20 registros. Mantém filtros de privacidade e limites de tamanho por registro do piloto inline. A importação no secundário ainda depende de validação real.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "target",
                  "confirm"
                ],
                "properties": {
                  "target": {
                    "type": "string",
                    "pattern": "^\\d+:\\d+@s\\.whatsapp\\.net$"
                  },
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              },
              "example": {
                "target": "5511999999999:2@s.whatsapp.net",
                "confirm": true
              }
            }
          }
        },
        "responses": {
          "400": {
            "description": "Alvo ou confirmação inválida"
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Laboratório desabilitado ou dispositivo ausente"
          },
          "409": {
            "description": "Dispositivo não conectado ou tarefa em andamento"
          },
          "410": {
            "description": "Envio manual removido; histórico somente durante novo vínculo"
          },
          "503": {
            "description": "Armazenamento indisponível ou confirmação AMQP incerta; a tarefa pode ter sido publicada"
          }
        },
        "operationId": "postManagerMobileDevicesIdCompanionHistory"
      }
    },
    "/manager/mobile-devices/{id}/companion-history/{operation}": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar progresso do histórico enviado ao secundário",
        "description": "Não envia mensagens. submitted confirma apenas a conclusão das chamadas de publicação do SDK, não recebimento nem importação; empty indica ausência de registros elegíveis; unknown indica envio parcial/incerto, sem retry automático; failed indica falha antes do envio; expired indica que o worker não executou no prazo. Sem mensagens, chaves ou URLs na resposta. Registro cifrado no Redis por uma hora; nova tarefa substitui a anterior. queued/running vencem após cinco minutos e aparecem como expired/unknown.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "operation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado e contagem, sem conteúdo das mensagens",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "submitted",
                        "empty",
                        "unknown",
                        "failed",
                        "expired"
                      ]
                    },
                    "sent": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Operação ausente",
            "substituída ou fora do escopo": null
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "getManagerMobileDevicesIdCompanionHistoryOperation"
      }
    },
    "/manager/mobile-devices/{id}/companions": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar, vincular ou revogar dispositivo secundário no worker",
        "description": "Administrador em qualquer servidor configurado. Enfileira um comando cifrado no Redis por até 10 minutos, processado pelo worker que já possui a conexão do principal, fora da fila de mensagens. Listagem usa o epoch persistido, não presença nem inventário remoto completo. QR é o conteúdo decodificado da imagem; code é o código de 8 caracteres solicitado pelo secundário (não SMS). Mutações exigem confirm=true. Sem repetição automática em resultado incerto. Consultar o identificador retornado até estado terminal.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "list",
                      "qr",
                      "code",
                      "revoke"
                    ]
                  },
                  "value": {
                    "type": "string",
                    "maxLength": 4096,
                    "writeOnly": true,
                    "description": "QR decodificado (puro ou com prefixo exato https://wa.me/settings/linked_devices# removido antes da Zapo), código ou JID do secundário, conforme action. O limite inclui o prefixo; outras URLs são rejeitadas."
                  },
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ],
                    "description": "Obrigatório para qr",
                    "code e revoke": null
                  },
                  "sendHistory": {
                    "type": "boolean",
                    "default": true,
                    "description": "Somente qr/code. false pula a exportação de mensagens antigas do Redis; mantém bootstrap e chaves obrigatórios. A opção vale apenas para o novo vínculo, sem alterar vínculos existentes."
                  }
                }
              },
              "example": {
                "action": "list"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Comando aceito, não significa vínculo concluído",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Comando ou confirmação inválida"
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Recurso desabilitado ou cadastro ausente"
          },
          "409": {
            "description": "Principal suspenso",
            "comando em andamento ou resultado incerto exige atualizar vínculos": null
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "postManagerMobileDevicesIdCompanions"
      }
    },
    "/manager/mobile-devices/{id}/companions/{operation}": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar resultado de comando de dispositivos vinculados",
        "description": "Somente administrador. Esta consulta de resultado não envia comandos ao WhatsApp. QR, código e chaves nunca são retornados. queued/running são estados pendentes; done confirma a chamada SDK; unknown indica resultado remoto incerto, sem retry automático; expired indica que o comando não foi executado no prazo. O comando list consulta os dispositivos da própria conta com source=server_device_list e ignora resultados concluídos em cache para refletir desvinculação remota; chamadas ainda em andamento são deduplicadas. Cada companion contém deviceJid e canRevoke; keyIndex e addedAtSeconds são opcionais, presentes somente quando há registro no epoch local. canRevoke=false indica vínculo listado no servidor sem material local necessário para revogar pelo SDK; use o WhatsApp para revogá-lo. Não garante presença online nem conclusão do bootstrap. Falha de consulta não é apresentada como lista vazia.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "operation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado sem material de autenticação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "done",
                        "unknown",
                        "expired"
                      ]
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Operação expirada",
            "substituída ou não pertence ao dispositivo": null
          },
          "409": {
            "description": "Principal suspenso ou configuração incompatível"
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "getManagerMobileDevicesIdCompanionsOperation"
      }
    },
    "/manager/session-transfers/backups": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Listar backups assíncronos de sessões Zapo normais",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador via Bearer, sem credenciais API. Retorna somente metadados, retidos por 24 horas.",
        "responses": {
          "200": {
            "description": "Lista tasks com id",
            "deviceId (telefone)": null,
            "status": null,
            "createdAt": null,
            "expiresAt e eventual erro": null
          }
        },
        "operationId": "getManagerSessionTransfersBackups",
        "parameters": []
      }
    },
    "/manager/session-transfers/{phone}/backup-tasks": {
      "parameters": [
        {
          "in": "path",
          "name": "phone",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Suspender e exportar sessão Zapo Redis em segundo plano",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador autenticado. Suspende a origem e gera arquivo criptografado stream-v2 em blocos, disponível no storage por 24 horas. Sem teto global de registros ou bytes; depende da capacidade do Redis e storage. Blocos de até 4 MiB e DUMP base64 de até 2000000 caracteres por registro. Sem truncamento. Falha recupera autoConnect anterior se a tarefa ainda controlar a configuração; sucesso mantém origem suspensa.",
        "requestBody": {
          "$ref": "#/paths/~1manager~1mobile-devices~1{id}~1backup-tasks/post/requestBody"
        },
        "responses": {
          "202": {
            "description": "Tarefa aceita; consultar lista para resultado"
          },
          "409": {
            "description": "Motor ou armazenamento incompatível; tarefa concorrente"
          }
        },
        "operationId": "postManagerSessionTransfersPhoneBackupTasks",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/session-transfers/{phone}/backup-tasks/{task}/download": {
      "parameters": [
        {
          "in": "path",
          "name": "phone",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "task",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Baixar .vipersession criptografado",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente administrador, Cache-Control no-store. Arquivos stream-v2 retornam metadados fileName e streamed=true; baixar os bytes pelo endpoint download/file. Backups legados retornam archive inline.",
        "responses": {
          "200": {
            "description": "JSON fileName e streamed=true",
            "ou fileName e archive para legado; somente administrador": null
          },
          "409": {
            "description": "Tarefa pendente ou substituída"
          },
          "410": {
            "description": "Arquivo expirado"
          }
        },
        "operationId": "getManagerSessionTransfersPhoneBackupTasksTaskDownload",
        "parameters": [
          {
            "name": "task",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/session-transfers/{phone}/backup-tasks/{task}/download/file": {
      "parameters": [
        {
          "in": "path",
          "name": "phone",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "task",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Baixar bytes do backup criptografado em streaming",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente administrador. Cache-Control no-store e Content-Disposition attachment. Arquivo retido por 24 horas no storage.",
        "responses": {
          "200": {
            "description": "Arquivo .vipersession criptografado",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "409": {
            "description": "Tarefa pendente ou substituída"
          },
          "410": {
            "description": "Arquivo expirado"
          },
          "503": {
            "description": "Storage indisponível"
          }
        },
        "operationId": "getManagerSessionTransfersPhoneBackupTasksTaskDownloadFile",
        "parameters": [
          {
            "name": "task",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/session-transfers/restore-uploads": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Iniciar upload em partes de backup stream-v2",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador (login ou stack; chaves API recusadas). Cria UUID vinculado ao administrador autenticado, com retenção de 24h. Redis guarda somente metadados e recibos SHA-256; bytes cifrados ficam no media storage padrão da instalação. Em Swarm, todas as réplicas web e o broker devem compartilhar S3/MinIO ou volume local. Não recebe senha nesta etapa. Capacidade do storage limita o tamanho total.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "size"
                ],
                "properties": {
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991,
                    "description": "Tamanho exato do arquivo em bytes"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload criado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partSize": {
                      "type": "integer",
                      "enum": [
                        8388608
                      ]
                    },
                    "parts": {
                      "type": "integer"
                    },
                    "expiresAt": {
                      "type": "integer",
                      "description": "Unix epoch em milissegundos"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "session_upload_invalid"
          },
          "401": {
            "description": "Autenticação obrigatória"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "503": {
            "description": "Redis ou storage indisponível"
          }
        },
        "operationId": "postManagerSessionTransfersRestoreUploads",
        "parameters": []
      }
    },
    "/manager/session-transfers/restore-uploads/{upload}": {
      "parameters": [
        {
          "in": "path",
          "name": "upload",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar upload e resultado assíncrono da restauração",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente o administrador dono. Estados uploading, restoring, ready, failed e interrupted. Inclui received, parts, expiresAt e result ou error quando disponíveis. Interrupção de processo/trava não reinicia a importação; revisar staging e destino. HTTP 202 da finalização não significa restauração concluída. Resposta sem senha ou chaves internas de objetos.",
        "responses": {
          "200": {
            "description": "Estado e resultado da tarefa"
          },
          "401": {
            "description": "Autenticação obrigatória"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Upload pertence a outro administrador"
          },
          "410": {
            "description": "Upload expirado"
          }
        },
        "operationId": "getManagerSessionTransfersRestoreUploadsUpload",
        "parameters": [
          {
            "name": "upload",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Cancelar upload e limpar partes temporárias",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente dono. Não cancela tarefas restoring/interrupted, pois a importação pode ter promovido chaves. Partes incompletas expiram com remoção agendada no broker; exige broker ativo. Não apaga credenciais da sessão.",
        "responses": {
          "200": {
            "description": "cancelled=true"
          },
          "404": {
            "description": "Upload de outro administrador"
          },
          "409": {
            "description": "session_upload_busy"
          },
          "410": {
            "description": "Upload expirado"
          }
        },
        "operationId": "deleteManagerSessionTransfersRestoreUploadsUpload",
        "parameters": [
          {
            "name": "upload",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/session-transfers/restore-uploads/{upload}/parts/{part}": {
      "put": {
        "tags": [
          "Manager"
        ],
        "summary": "Enviar parte binária de até 8 MiB",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Partes sequenciais, índice zero-based. Todas têm 8 MiB exceto a última, cujo tamanho restante deve ser exato. SHA-256 hexadecimal obrigatório; bytes e digest verificados antes do recibo. Repetição de uma parte confirmada só aceita bytes idênticos. Não é multipart/form-data de arquivo inteiro: cada parte é uma requisição separada, abaixo do limite padrão do Cloudflare. Respeitar limites menores configurados no proxy. Sem alteração de dados da sessão nesta fase.",
        "parameters": [
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "path",
            "name": "part",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "in": "header",
            "name": "X-Part-SHA256",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contadores received e parts confirmados"
          },
          "400": {
            "description": "Índice inválido",
            "tamanho incompleto ou SHA-256 divergente": null
          },
          "401": {
            "description": "Autenticação obrigatória antes de consumir bytes"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Upload pertence a outro administrador"
          },
          "409": {
            "description": "Ordem inválida",
            "conflito de parte ou trava ocupada/perdida": null
          },
          "410": {
            "description": "Upload expirado"
          },
          "413": {
            "description": "Parte ultrapassa o tamanho esperado ou limite do proxy"
          },
          "415": {
            "description": "application/octet-stream obrigatório"
          },
          "503": {
            "description": "Storage indisponível"
          }
        },
        "operationId": "putManagerSessionTransfersRestoreUploadsUploadPartsPart"
      }
    },
    "/manager/session-transfers/restore-uploads/{upload}/complete": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Finalizar upload e iniciar restauração em segundo plano",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Exige todas as partes confirmadas. Recebe senha somente nesta requisição; não a persiste. Reconstrói stream ordenado com no máximo 8 MiB por parte, verifica novamente os recibos e usa o importador autenticado stream-v2. Valida fechamento e identidade antes de ativar sessão, sem sobrescrever destino. Consulta GET para resultado; não reenviar backup por timeout HTTP. Processo reiniciado perde execução e retorna interrupted, exigindo revisão manual. Partes são limpas após resultado e possuem remoção agendada em 24h.",
        "parameters": [
          {
            "in": "path",
            "name": "upload",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "password",
                  "confirmOriginOffline"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 12,
                    "maxLength": 128,
                    "writeOnly": true
                  },
                  "confirmOriginOffline": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Solicitação aceita ou já registrada; consultar GET para resultado efetivo"
          },
          "400": {
            "description": "Senha ou confirmação inválida"
          },
          "401": {
            "description": "Autenticação obrigatória"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Upload pertence a outro administrador"
          },
          "409": {
            "description": "Partes ausentes ou trava ocupada"
          },
          "410": {
            "description": "Upload expirado"
          }
        },
        "operationId": "postManagerSessionTransfersRestoreUploadsUploadComplete"
      }
    },
    "/manager/session-transfers/restore-stream": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Restaurar backup stream-v2 em lotes",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador autenticado antes da leitura. Corpo binário começa com uma linha JSON contendo password e confirmOriginOffline=true, seguida de newline e dos bytes originais do arquivo stream-v2. Sem teto global; limites por bloco e registro. Valida arquivo inteiro e identidade antes de ativar a sessão. Promove lotes de 100 registros sem sobrescrever destino. Preserva TTL, configura autoConnect=true e webhooks vazios. Interrupção durante promoção exige revisão; não repetir importação cegamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Restaurada com autoConnect=true; conexão solicitada ou warning restore_connection_dispatch_failed"
          },
          "400": {
            "description": "Arquivo",
            "senha": null,
            "integridade ou identidade inválidos": null
          },
          "401": {
            "description": "Autenticação obrigatória"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "409": {
            "description": "Destino ocupado ou session_restore_rollback_pending; revisar antes de repetir"
          },
          "413": {
            "description": "Bloco ou registro individual acima do limite de segurança"
          },
          "415": {
            "description": "Content-Type deve ser application/octet-stream"
          },
          "503": {
            "description": "Redis ou storage indisponível"
          }
        },
        "operationId": "postManagerSessionTransfersRestoreStream",
        "parameters": []
      }
    },
    "/manager/session-transfers/restore": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Restaurar sessão vinculada com conexão automática sem sobrescrever o destino",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Compatibilidade com backups legados Zapo Redis. Até 50000 registros, 8 MiB internos e 16 MiB por arquivo legado. JSON HTTP até 17 MiB após autenticar administrador. Para stream-v2 usar restore-stream. Webhooks vazios; autoConnect=true. Solicita conexão ao worker após liberar a trava. Confirmação obrigatória da origem offline.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "archive",
                  "password",
                  "confirmOriginOffline"
                ],
                "properties": {
                  "archive": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "writeOnly": true
                  },
                  "confirmOriginOffline": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sessão restaurada com autoConnect=true; status connection_requested ou disconnected com warning restore_connection_dispatch_failed se falhar a solicitação ao worker. Não repetir importação"
          },
          "400": {
            "description": "Arquivo",
            "senha ou identidade incompatível": null
          },
          "409": {
            "description": "Destino ocupado; nenhum dado sobrescrito"
          },
          "413": {
            "description": "Corpo JSON ou arquivo acima do limite permitido"
          }
        },
        "operationId": "postManagerSessionTransfersRestore",
        "parameters": []
      }
    },
    "/manager/session-transfers/{phone}/transfer-removal": {
      "parameters": [
        {
          "in": "path",
          "name": "phone",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar se a remoção local após migração está liberada",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador; verifica checkpoint de backup e suspensão da origem.",
        "responses": {
          "200": {
            "description": "Objeto eligible; exige backup concluído e suspensão"
          }
        },
        "operationId": "getManagerSessionTransfersPhoneTransferRemoval",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Remover origem após migração, sem logout no WhatsApp",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Exige senha do administrador, telefone e confirmação da validação do backup no destino. Remove cadastro, índice e atribuição ativa ao usuário, preservando histórico de atribuições. Apenas limpeza local, sem revogação remota.",
        "requestBody": {
          "$ref": "#/paths/~1manager~1mobile-devices~1{id}~1transfer-removal/delete/requestBody"
        },
        "responses": {
          "204": {
            "description": "Credenciais Zapo e configuração locais removidas"
          },
          "401": {
            "description": "Senha do administrador incorreta"
          },
          "409": {
            "description": "Backup ou suspensão ausente",
            "ou sessão em uso": null
          },
          "429": {
            "description": "Limite de tentativas de senha"
          }
        },
        "operationId": "deleteManagerSessionTransfersPhoneTransferRemoval",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/mobile-devices/backups": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Listar tarefas de backup dos dispositivos",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente administrador autenticado, sem credencial API. Retorna metadados, nunca a senha ou o arquivo. Atualizar ao retornar ao painel.",
        "responses": {
          "200": {
            "description": "Tarefas running, ready, failed ou interrupted. Inclui id, deviceId, createdAt, expiresAt e eventual código de erro."
          }
        },
        "operationId": "getManagerMobileDevicesBackups",
        "parameters": []
      }
    },
    "/manager/mobile-devices/{id}/backup-tasks": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Gerar backup em segundo plano",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente administrador. Uma tarefa simultânea. Senha apenas em memória durante execução; arquivo criptografado disponível por 24 horas após conclusão. Reinício durante geração não retoma automaticamente; após 10 minutos aparece interrupted. Mantém somente o último resultado por dispositivo.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "password",
                  "confirmSuspend",
                  "mode"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password",
                    "writeOnly": true,
                    "minLength": 12,
                    "maxLength": 128
                  },
                  "confirmSuspend": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "credentials",
                      "complete"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Tarefa aceita; consultar a lista de backups para o resultado"
          },
          "400": {
            "description": "Confirmação ou senha inválida"
          },
          "409": {
            "description": "Já existe uma tarefa em execução"
          }
        },
        "operationId": "postManagerMobileDevicesIdBackupTasks",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/mobile-devices/{id}/backup-tasks/{task}/download": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "task",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Baixar arquivo criptografado de backup concluído",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Somente administrador autenticado. Resposta JSON com fileName e archive para download pelo navegador. Cache-Control no-store. A senha não é retornada.",
        "responses": {
          "200": {
            "description": "Arquivo criptografado disponível"
          },
          "409": {
            "description": "Tarefa pendente",
            "substituída ou inexistente": null
          },
          "410": {
            "description": "Arquivo expirado"
          }
        },
        "operationId": "getManagerMobileDevicesIdBackupTasksTaskDownload",
        "parameters": [
          {
            "name": "task",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/mobile-devices/{id}/transfer-removal": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar liberação de remoção local após migração",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Administrador autenticado. Requer checkpoint de backup concluído e origem suspensa.",
        "responses": {
          "200": {
            "description": "Elegibilidade local; não confirma restauração no destino.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eligible": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "getManagerMobileDevicesIdTransferRemoval",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Remover somente desta instância após migração",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Confere novamente a senha do administrador conectado, com limite de tentativas. Exige backup concluído, suspensão e confirmação humana da validação no destino. Remove a atribuição ativa ao usuário, preservando seu histórico. Não faz logout remoto nem revoga vínculos WhatsApp. Reativar a origem invalida o checkpoint.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "phone",
                  "confirm",
                  "backupValidated",
                  "password"
                ],
                "properties": {
                  "phone": {
                    "type": "string"
                  },
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "backupValidated": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "writeOnly": true,
                    "maxLength": 4096
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Cadastro e credenciais locais removidos"
          },
          "400": {
            "description": "Confirmação inválida"
          },
          "401": {
            "description": "Senha inválida"
          },
          "403": {
            "description": "Administrador requerido; credencial API não autorizada"
          },
          "409": {
            "description": "Backup ou suspensão ausente; conflito de ownership"
          },
          "429": {
            "description": "Limite de tentativas de senha"
          }
        },
        "operationId": "deleteManagerMobileDevicesIdTransferRemoval",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/mobile-devices/{id}/backup": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Suspender e exportar backup criptografado do dispositivo principal",
        "description": "Somente administrador, com Redis e chave de criptografia configurada. Suspende a conexão sem remover webhooks. Exporta auth, Signal, prekeys, sender keys, app-state, privacy tokens, companions e registro em .viperdevice cifrado por senha (AES-256-GCM e scrypt). mode=complete inclui também mensagens de todos os tipos, índices, contatos, mapeamentos UnoID/provider e status, preservando expiração. mode=credentials é o padrão da API para compatibilidade; o painel seleciona complete. Não inclui arquivos de mídia, webhooks, usuários ou tokens da stack. Limites de 16 MiB por arquivo, 8 MiB de conteúdo interno e 50000 registros, sem truncamento silencioso. A origem permanece com autoConnect=false, inclusive se o download falhar. Nunca reconecte a origem após começar a usar o destino.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "password",
                  "confirmSuspend"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 12,
                    "maxLength": 128,
                    "writeOnly": true
                  },
                  "confirmSuspend": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "credentials",
                      "complete"
                    ],
                    "default": "credentials"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conteúdo criptografado para download; resposta com Cache-Control no-store",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fileName": {
                      "type": "string"
                    },
                    "archive": {
                      "type": "string",
                      "description": "Envelope JSON cifrado",
                      "salvar sem alterações": null
                    },
                    "sourceSuspended": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Senha ou confirmação inválida"
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "409": {
            "description": "Dispositivo incompatível",
            "ocupado ou ainda encerrando a conexão; aguardar e repetir": null
          },
          "413": {
            "description": "Backup excedeu os limites de tamanho ou quantidade de chaves"
          },
          "503": {
            "description": "Falha operacional; origem pode já estar suspensa"
          }
        },
        "operationId": "postManagerMobileDevicesIdBackup"
      }
    },
    "/manager/mobile-devices/restore": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Restaurar dispositivo principal a partir de backup criptografado",
        "description": "Somente administrador em qualquer servidor configurado. Arquivo até 16 MiB; Zapo 1.9.0, store-redis 1.3.0, mesmo prefixo Redis e formato DUMP compatível. Recusa cadastro, configuração ou credenciais preexistentes para o número. Reprotege o registro com a chave da stack de destino. Restaura com autoConnect=true e sem webhooks; solicita conexão ao worker após liberar a trava. Não solicita SMS nem garante validade remota de credenciais revogadas. Exige confirmação da origem desligada. Falha de publicação retorna warning restore_connection_dispatch_failed sem desfazer a restauração.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "archive",
                  "password",
                  "confirmOriginOffline"
                ],
                "properties": {
                  "archive": {
                    "type": "string",
                    "maxLength": 16777216,
                    "description": "Conteúdo integral do arquivo .viperdevice"
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 12,
                    "maxLength": 128,
                    "writeOnly": true
                  },
                  "confirmOriginOffline": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dispositivo restaurado com conexão automática habilitada; solicitação ao worker não garante conexão concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "device": {
                      "$ref": "#/components/schemas/MobileDeviceDraft"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "connection_requested",
                        "disconnected"
                      ]
                    },
                    "autoConnect": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "warning": {
                      "type": "string",
                      "enum": [
                        "restore_connection_dispatch_failed"
                      ]
                    },
                    "restored": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Arquivo inválido",
            "incompatível": null,
            "senha incorreta ou confirmação ausente": null
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "409": {
            "description": "Destino ocupado ou com dados existentes; nada é sobrescrito"
          },
          "413": {
            "description": "Arquivo excedeu o limite"
          },
          "503": {
            "description": "Falha de armazenamento ou formato DUMP incompatível"
          }
        },
        "operationId": "postManagerMobileDevicesRestore",
        "parameters": []
      }
    },
    "/manager/mobile-devices/{id}/connection": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar conexão do dispositivo principal",
        "description": "Somente administrador no servidor configurado. Consulta a sessão Uno pelo número canônico registrado; não abre socket nem retorna credenciais.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado persistido da conexão, não confirmação de entrega de mensagens",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "phone": {
                      "type": "string"
                    },
                    "imported": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "409": {
            "description": "Registro incompleto ou sessão conflitante"
          }
        },
        "operationId": "getManagerMobileDevicesIdConnection"
      },
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Importar registro e conectar dispositivo principal à Zapo",
        "description": "Disponível no servidor configurado. Exige registro concluído e confirmação explícita. Preserva o registro cifrado, importa auth nativo somente se vazio e compatível, usa lease da sessão e publica a conexão para o worker existente. Habilita autoConnect somente após importação. Nunca sobrescreve auth atualizado nem restaura auth removido após importação. Uma resposta 202 não significa conectado; consultar GET. Não envia mensagens de teste.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              },
              "example": {
                "confirm": true
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Credenciais preservadas e solicitação publicada ao worker"
          },
          "400": {
            "description": "Confirmação ausente"
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "409": {
            "description": "Registro incompleto",
            "sessão em uso ou conflito de identidade": null
          },
          "503": {
            "description": "Falha de armazenamento ou publicação; consultar estado antes de repetir"
          }
        },
        "operationId": "postManagerMobileDevicesIdConnection"
      }
    },
    "/manager/mobile-devices/{id}/registration": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar estado do registro mobile experimental",
        "description": "Somente administrador com Bearer. Proteção das credenciais provisionada automaticamente no Redis persistente; sem nova ENV em instalações novas. Retorna estado público, nunca OTP ou credenciais. Registrado não significa conectado pela Zapo. Operação interrompida fica incerta, sem reenvio automático.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado público do registro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRegistrationStatus"
                }
              }
            }
          },
          "401": {
            "description": "Bearer ausente ou inválido"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Cadastro ausente"
          },
          "503": {
            "description": "Registro desativado ou armazenamento indisponível"
          }
        },
        "operationId": "getManagerMobileDevicesIdRegistration"
      }
    },
    "/manager/mobile-devices/{id}/registration/check": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar confirmação feita no aparelho principal",
        "description": "Consulta somente /exist com as mesmas chaves após device_confirm_or_second_code. Não solicita nem verifica código e não conecta automaticamente. Exige resposta ok, login canônico válido e ausência de pendência; valida identidade e grava por CAS. Intervalo mínimo de 15 segundos entre consultas. Falhas preservam credenciais e prazos de reenvio. A sessão mantém o número cadastrado; a autenticação usa o canônico confirmado pelo WhatsApp.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Registro confirmado; conectar à Zapo pelo fluxo existente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRegistrationStatus"
                }
              }
            }
          },
          "400": {
            "description": "Confirmação inválida"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Cadastro ausente"
          },
          "409": {
            "description": "Estado incompatível",
            "identidade divergente ou consulta recente": null
          },
          "503": {
            "description": "Confirmação não comprovada ou consulta indisponível; nenhuma solicitação de código"
          }
        },
        "operationId": "postManagerMobileDevicesIdRegistrationCheck"
      }
    },
    "/manager/mobile-devices/{id}/registration/request": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Solicitar código por SMS ou ligação de voz",
        "description": "Administrador e consentimento explícito. method=sms (padrão) ou voice, inclusive telefone fixo. Uma tentativa por ação, sem troca automática de método. Persiste chaves antes da rede e preserva identidade nos reenvios. Nova solicitação exige confirmResend=true e canResendSms ou canResendVoice conforme o método. fail/blocked na etapa request permite nova tentativa manual por qualquer método quando não há pendência ou prazo remoto ainda vigente; sem prazo, não impõe espera local. Respeita espera remota; desafios e resultados incertos continuam bloqueados. Não garante aceitação do provedor nem conecta automaticamente pela Zapo.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "sms",
                      "voice"
                    ],
                    "default": "sms",
                    "description": "Método explicitamente escolhido; sem fallback automático"
                  },
                  "confirmResend": {
                    "type": "boolean",
                    "description": "Após no_routes, permite repetir o método recusado após espera explícita do provedor, inclusive zero; sem espera informada, permite apenas o método alternativo. Exige consentimento e respeita prazos independentes de SMS/ligação e pendências. Consentimento para reenvio quando canResendSms=true para sms ou canResendVoice=true para voice, incluindo código não recebido em code_required. Respeita a espera informada no envio aceito; sem prazo nesse sucesso, permite reenvio manual. device_confirm_or_second_code permite reenvio comum após prazo remoto conhecido para o método, sem outra pendência e sem teto local; não comprova suporte ao segundo código."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consulte status; bloqueio não equivale a SMS enviado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRegistrationStatus"
                }
              }
            }
          },
          "400": {
            "description": "Consentimento inválido"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Cadastro ausente"
          },
          "409": {
            "description": "Operação já iniciada ou estado incompatível"
          },
          "503": {
            "description": "Registro desativado ou infraestrutura indisponível"
          }
        },
        "operationId": "postManagerMobileDevicesIdRegistrationRequest"
      }
    },
    "/manager/mobile-devices/{id}/registration/verify": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Confirmar código SMS do registro mobile experimental",
        "description": "Código de seis dígitos como string. Aceito após code_required ou recuperação explícita com confirmRecovery=true quando canRetryVerification=true. Recuperação preserva chaves, não solicita SMS, exige intervalo de 60 segundos e limita a três confirmações totais. Autorizações no aparelho são concluídas manualmente e consultadas em registration/check sem novo código. A sessão preserva o número cadastrado e a autenticação usa o canônico retornado pelo WhatsApp. PIN, CAPTCHA e outros desafios não são contornados. Nunca inicia socket Zapo.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "pattern": "^[0-9]{6}$",
                    "writeOnly": true
                  },
                  "confirmRecovery": {
                    "type": "boolean",
                    "description": "Consentimento explícito para recuperação permitida pelo estado atual"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estado atualizado; registrado não equivale a conectado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRegistrationStatus"
                }
              }
            }
          },
          "400": {
            "description": "Código inválido"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Cadastro ausente"
          },
          "409": {
            "description": "Estado incompatível ou operação concorrente"
          },
          "503": {
            "description": "Registro desativado ou infraestrutura indisponível"
          }
        },
        "operationId": "postManagerMobileDevicesIdRegistrationVerify"
      }
    },
    "/manager/mobile-devices/capabilities": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar capacidades Mobile Primary",
        "description": "Exige Authorization: Bearer administrativo. Disponível em qualquer UNOAPI_SERVER_NAME, Docker standalone ou Swarm. Web e worker compartilham a chave interna provisionada automaticamente na mesma base Redis persistente, independente do token da API. Instalações legadas preservam MOBILE_REGISTRATION_KEY durante a migração inicial. Runtime SMS incluído na imagem. VoIP requer serviço integrado configurado. A consulta não abre sockets nem envia SMS.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Capacidades e configuração do Mobile Primary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "experimental": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "draftManagement": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "smsRegistration": {
                      "type": "boolean",
                      "description": "Disponível com chave de criptografia válida; aceitação do registro depende do WhatsApp"
                    },
                    "credentialImport": {
                      "type": "boolean"
                    },
                    "primaryConnection": {
                      "type": "boolean"
                    },
                    "companionQr": {
                      "type": "boolean"
                    },
                    "companionCode": {
                      "type": "boolean"
                    },
                    "voip": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "",
                        "mobile_registration_key_required"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Bearer ausente ou inválido"
          },
          "403": {
            "description": "Administrador obrigatório; chaves pessoais não são aceitas"
          },
          "404": {
            "description": "Funcionalidade experimental desativada"
          },
          "503": {
            "description": "Autenticação indisponível"
          }
        },
        "operationId": "getManagerMobileDevicesCapabilities",
        "parameters": []
      }
    },
    "/manager/mobile-devices": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Listar rascunhos de dispositivos principais",
        "description": "Somente administrador. Retorna até 100 rascunhos, ordenados por telefone. Esses registros não são sessões conectadas nem reservam o número. Authorization exige Bearer; tokens na URL não são aceitos. Cache-Control: no-store.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Rascunhos de dispositivos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devices": {
                      "type": "array",
                      "maxItems": 100,
                      "items": {
                        "$ref": "#/components/schemas/MobileDeviceDraft"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credencial ausente ou inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Funcionalidade experimental desativada"
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "getManagerMobileDevices",
        "parameters": []
      },
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Cadastrar rascunho de dispositivo principal",
        "description": "Salva somente metadados no Redis; não solicita SMS, não cria credenciais, não conecta e não muda sessões existentes. Requer administrador e Bearer. Consentimento obrigatório; telefone único entre rascunhos. Repetição retorna 409, sem criar duplicata. Nome máximo de 80 caracteres sem caracteres de controle. Não aceita proxy, OTP, tokens, credenciais, estado ou atribuição de responsável.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "phone",
                  "name",
                  "platform",
                  "accountType",
                  "labConsent"
                ],
                "properties": {
                  "phone": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{7,14}$"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "platform": {
                    "type": "string",
                    "enum": [
                      "android",
                      "ios"
                    ]
                  },
                  "accountType": {
                    "type": "string",
                    "enum": [
                      "personal",
                      "business"
                    ]
                  },
                  "labConsent": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              },
              "example": {
                "phone": "5511999999999",
                "name": "Laboratório",
                "platform": "android",
                "accountType": "personal",
                "labConsent": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Rascunho criado, não registrado no WhatsApp",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileDeviceDraft"
                }
              }
            }
          },
          "400": {
            "description": "Dados inválidos",
            "campos extras ou consentimento ausente": null
          },
          "401": {
            "description": "Credencial ausente ou inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Funcionalidade experimental desativada"
          },
          "409": {
            "description": "Telefone já cadastrado ou limite de 100 rascunhos"
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "postManagerMobileDevices",
        "parameters": []
      }
    },
    "/manager/mobile-devices/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar rascunho de dispositivo principal",
        "description": "Consulta administrativa, com Bearer e flag experimental. Não consulta o WhatsApp. O ID identifica somente o cadastro local.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Metadados do cadastro experimental",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileDeviceDraft"
                }
              }
            }
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Rascunho inexistente ou funcionalidade desativada"
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "getManagerMobileDevicesId",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Remover somente um rascunho experimental",
        "description": "Requer administrador, Bearer e flag experimental. Exige confirm=true. Compare-and-delete impede apagar um registro substituído concorrentemente. Não desconecta nem exclui contas WhatsApp, credenciais, mídias, webhooks ou sessões vinculadas. Somente estado draft pode ser removido por esta operação.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  }
                }
              },
              "example": {
                "confirm": true
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Rascunho removido"
          },
          "400": {
            "description": "Confirmação inválida"
          },
          "401": {
            "description": "Credencial inválida"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Rascunho inexistente ou funcionalidade desativada"
          },
          "409": {
            "description": "Cadastro alterado concorrentemente ou não está em draft"
          },
          "503": {
            "description": "Armazenamento indisponível"
          }
        },
        "operationId": "deleteManagerMobileDevicesId",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/manager/mobile-devices/{id}/full": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Excluir definitivamente dispositivo principal e credenciais locais",
        "description": "Exclusivo de administrador. Exige confirmação, aceite de novo SMS e número exato do cadastro. Marca exclusão em andamento, bloqueia registro/importação, suspende a conexão e aguarda a liberação da lease do worker antes de limpar o store Zapo, configuração, registro SMS cifrado e cadastro. Não exclui a conta no WhatsApp. Novo uso exige novo registro por SMS, sujeito às validações e esperas do provider. Mídias, histórico de webhooks e atribuições históricas são preservados. A atribuição ativa ao usuário é removida para não manter uma sessão pendente na lista. Em caso de falha parcial, repita a exclusão; o cadastro fica marcado como deleting.",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "confirm",
                  "acknowledgeNewSms",
                  "phone"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "acknowledgeNewSms": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "phone": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{7,14}$"
                  }
                }
              },
              "example": {
                "confirm": true,
                "acknowledgeNewSms": true,
                "phone": "5511999999999"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Dispositivo e credenciais locais excluídos"
          },
          "400": {
            "description": "Confirmação incompleta ou telefone divergente"
          },
          "401": {
            "description": "Bearer obrigatório"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "404": {
            "description": "Cadastro inexistente"
          },
          "409": {
            "description": "Conflito ou conexão ainda encerrando. Aguarde e repita sem solicitar SMS."
          },
          "503": {
            "description": "Falha parcial no armazenamento. Repita para concluir."
          }
        },
        "operationId": "deleteManagerMobileDevicesIdFull",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/redis/tree": {
      "get": {
        "tags": [
          "Administração"
        ],
        "summary": "Navegar na árvore de chaves Redis",
        "description": "Lista até 200 nós por prefixo permitido unoapi- ou unoapi:, incluindo as chaves públicas users, names, assignments, history e keys de manager-identity:{v1}:. Identidades e histórico de webhooks são somente leitura; suas subárvores não podem ser excluídas. Prefixo vazio lista raízes; não use curingas. descendantCount é informativo. Acesso exclusivo de administrador.",
        "parameters": [
          {
            "name": "prefix",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "unoapi:exemplo:"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Nós da árvore",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prefix": {
                      "type": "string"
                    },
                    "nodes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "path": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "branch",
                              "key"
                            ]
                          },
                          "descendantCount": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "prefix": "unoapi:exemplo:",
                  "nodes": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminRedisTree",
        "x-source-route": "/admin/redis/tree",
        "x-source-controller": "redisAdminController.tree"
      },
      "delete": {
        "tags": [
          "Administração"
        ],
        "summary": "Excluir todas as chaves de um prefixo Redis",
        "description": "Exclusão destrutiva sem dry-run. Prefixo permitido deve terminar em dois-pontos; confirm deve ser idêntico. Faça backup recuperável antes de executar.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "prefix",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "unoapi:exemplo:"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "confirm": "unoapi:exemplo:"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quantidade removida",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prefix": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "prefix": "unoapi:exemplo:",
                  "removed": 1
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "redis_prefix_confirmation_mismatch"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminRedisTree",
        "x-source-route": "/admin/redis/tree",
        "x-source-controller": "redisAdminController.removeTree"
      }
    },
    "/admin/voip/console/ai/models": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar modelos atuais do OpenRouter para IA pós-chamada",
        "description": "Catálogo público consultado pelo worker, sem enviar chave ou áudio. Somente administradores. Não valida crédito nem acesso da chave ao modelo.",
        "parameters": [
          {
            "in": "query",
            "name": "provider",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "openrouter"
              ]
            }
          },
          {
            "in": "query",
            "name": "purpose",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "transcription",
                "summary"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Modelos compatíveis com a finalidade solicitada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "models": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Provedor ou finalidade inválidos"
          },
          "401": {
            "description": "Autenticação obrigatória"
          },
          "403": {
            "description": "Administrador obrigatório"
          },
          "502": {
            "description": "Catálogo indisponível ou inválido"
          }
        },
        "operationId": "getAdminVoipConsoleAiModels"
      }
    },
    "/admin/voip/console/bootstrap": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Consultar bootstrap do console VoIP",
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Usuário recebe apenas inventário filtrado e capacidades. Não retorna configuração global ou credenciais compartilhadas. Histórico/gravações dependem de upstream capabilities.managerSessionHistoryScope=1 e das duas versões atualizadas. Com upstream antigo, history=false e recordings=false (acesso negado por segurança).",
        "responses": {
          "200": {
            "description": "Estado usado pela página Telefonia do Manager.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VoipBootstrap"
                    },
                    {
                      "$ref": "#/components/schemas/ManagerVoipBootstrap"
                    }
                  ]
                },
                "examples": {
                  "usuario": {
                    "summary": "Serviço VoIP com escopo de histórico compatível",
                    "value": {
                      "capabilities": {
                        "scoped": true,
                        "activeCalls": true,
                        "callCommands": true,
                        "createCalls": false,
                        "history": true,
                        "recordings": true,
                        "configuration": false,
                        "lines": true,
                        "automaticExtensions": true,
                        "extensionCredentials": true,
                        "extensionSipMode": true,
                        "disconnectRegistration": false,
                        "basicInboundSettings": false
                      },
                      "accounts": [],
                      "sessions": [],
                      "extensions": [],
                      "zapoLines": [],
                      "bridges": [],
                      "calls": []
                    }
                  },
                  "upstreamLegado": {
                    "summary": "Upstream antigo: histórico e gravações bloqueados",
                    "value": {
                      "capabilities": {
                        "scoped": true,
                        "activeCalls": true,
                        "callCommands": true,
                        "createCalls": false,
                        "history": false,
                        "recordings": false,
                        "configuration": false,
                        "lines": true,
                        "automaticExtensions": true,
                        "extensionCredentials": true,
                        "extensionSipMode": true,
                        "disconnectRegistration": false,
                        "basicInboundSettings": false
                      },
                      "accounts": [],
                      "sessions": [],
                      "extensions": [],
                      "zapoLines": [],
                      "bridges": [],
                      "calls": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Serviço VoIP não configurado."
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleBootstrap",
        "parameters": []
      }
    },
    "/admin/voip/console/extensions/{extensionId}/sip-mode": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Alterar modo SIP de um ramal",
        "description": "Administrador ou usuário Manager padrão, somente ramal zapo_auto próprio, não compartilhado e com vínculo comprovado. Usuário usa o ID exato; ramais manuais, trunks externos/compartilhados e aliases ambíguos são negados. Seleciona extension ou trunk sem editar outros campos. Corpo estrito: apenas sipEndpointMode. Um ramal automático próprio em trunk continua visível e pode ter suas credenciais consultadas. Executar altera o modo real; não rotaciona senha nem desconecta registros automaticamente. Fluxos legados permanecem inalterados.",
        "parameters": [
          {
            "name": "extensionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sipEndpointMode"
                ],
                "additionalProperties": false,
                "properties": {
                  "sipEndpointMode": {
                    "type": "string",
                    "enum": [
                      "extension",
                      "trunk"
                    ]
                  }
                }
              },
              "example": {
                "sipEndpointMode": "extension"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Modo salvo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "extensionId",
                    "sipEndpointMode"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "extensionId": {
                      "type": "string"
                    },
                    "sipEndpointMode": {
                      "type": "string",
                      "enum": [
                        "extension",
                        "trunk"
                      ]
                    }
                  }
                },
                "example": {
                  "extensionId": "1001",
                  "sipEndpointMode": "extension"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_sip_endpoint_mode"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "manager_voip_forbidden"
                }
              }
            }
          },
          "404": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "extension_not_found"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleExtensionsExtensionIdSipMode"
      }
    },
    "/admin/voip/console/companies": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar empresas",
        "description": "Lista empresas com segredos omitidos.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipCompany"
                      }
                    }
                  }
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleCompanies",
        "parameters": []
      }
    },
    "/admin/voip/console/companies/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar empresas",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipCompany"
              },
              "example": {
                "label": "Empresa de exemplo",
                "timeZone": "America/Cuiaba",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleCompaniesId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir empresas",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleCompaniesId"
      }
    },
    "/admin/voip/console/accounts": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar contas/linhas",
        "description": "Lista contas/linhas com segredos omitidos.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipAccount"
                      }
                    }
                  }
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleAccounts",
        "parameters": []
      }
    },
    "/admin/voip/console/accounts/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar contas/linhas",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipAccount"
              },
              "example": {
                "label": "Linha de exemplo",
                "companyId": "empresa-exemplo",
                "phoneNumber": "5511999999999",
                "enabled": true,
                "maxConcurrentCalls": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleAccountsId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir contas/linhas",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleAccountsId"
      }
    },
    "/admin/voip/console/sessions": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar sessões",
        "description": "Lista sessões com segredos omitidos.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipSession"
                      }
                    }
                  }
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleSessions",
        "parameters": []
      }
    },
    "/admin/voip/console/sessions/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar sessões",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipSession"
              },
              "example": {
                "label": "Sessão de exemplo",
                "companyId": "empresa-exemplo",
                "accountId": "linha-exemplo",
                "unoSession": "5511999999999",
                "maxConcurrentCalls": 2,
                "routing": {
                  "basicInboundEnabled": true
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleSessionsId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir sessões",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleSessionsId"
      }
    },
    "/admin/voip/console/extensions": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar ramais",
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Para usuário, lista somente ramais automáticos próprios, não compartilhados, sem senha. Ramais automáticos próprios em extension ou trunk permanecem visíveis. Ramais manuais, trunks externos/compartilhados, aliases ambíguos e grupos compartilhados são recusados/omitidos.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/VoipExtension"
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ManagerVoipExtension"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleExtensions",
        "parameters": []
      }
    },
    "/admin/voip/console/extensions/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar ramais",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipExtension"
              },
              "example": {
                "displayName": "Ramal de exemplo",
                "username": "1001",
                "companyId": "empresa-exemplo",
                "type": "both",
                "password": "SUBSTITUA_POR_SENHA_FORTE",
                "enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleExtensionsId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir ramais",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleExtensionsId"
      }
    },
    "/admin/voip/console/lineGroups": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar grupos de linhas",
        "description": "Lista grupos de linhas com segredos omitidos.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipLineGroup"
                      }
                    }
                  }
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleLineGroups",
        "parameters": []
      }
    },
    "/admin/voip/console/lineGroups/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar grupos de linhas",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipLineGroup"
              },
              "example": {
                "label": "Grupo de linhas",
                "companyId": "empresa-exemplo",
                "inboundSessionIds": [
                  "sessao-exemplo"
                ],
                "outboundPrioritySessionIds": [
                  "sessao-exemplo"
                ],
                "targetExtensionGroupIds": [
                  "grupo-ramais"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleLineGroupsId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir grupos de linhas",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleLineGroupsId"
      }
    },
    "/admin/voip/console/extensionGroups": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar grupos de ramais",
        "description": "Lista grupos de ramais com segredos omitidos.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Itens cadastrados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipExtensionGroup"
                      }
                    }
                  }
                },
                "example": {
                  "items": []
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminVoipConsoleExtensionGroups",
        "parameters": []
      }
    },
    "/admin/voip/console/extensionGroups/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar grupos de ramais",
        "description": "ID do caminho identifica o recurso. Requer vínculos existentes e consistentes. Recursos automáticos preservam campos gerenciados; modificá-los pode retornar 409. Senha vazia preserva a existente.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipExtensionGroup"
              },
              "example": {
                "label": "Grupo de ramais",
                "companyId": "empresa-exemplo",
                "extensionIds": [
                  "1001"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração salva com segredos omitidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_configuration"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "automatic_resource_managed"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleExtensionGroupsId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir grupos de ramais",
        "description": "Recursos referenciados, empresa padrão e recursos automáticos gerenciados são protegidos (409). Não há confirmação no corpo; o envio confirma a operação.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuração resultante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "409": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "resource_in_use"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleExtensionGroupsId"
      }
    },
    "/manager/login": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Entrar no Manager",
        "description": "Local, não implantado. admin usa o token da stack como senha; usuários usam suas senhas. Retorna token e user; login expira em 12 horas.",
        "x-release-status": "local-not-deployed",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "username",
                  "password"
                ],
                "properties": {
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "writeOnly": true
                  }
                }
              },
              "example": {
                "username": "admin",
                "password": "SUBSTITUA_PELO_TOKEN_DA_STACK"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "token",
                    "user"
                  ],
                  "properties": {
                    "token": {
                      "type": "string"
                    },
                    "user": {
                      "$ref": "#/components/schemas/ManagerUser"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "429": {
            "description": "Limite de tentativas de login excedido"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerLogin",
        "parameters": []
      }
    },
    "/manager/me": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar identidade do Manager",
        "description": "Papel resolvido pelo servidor a partir do token, sem aceitar claims do cliente.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "user"
                  ],
                  "properties": {
                    "user": {
                      "type": "object",
                      "required": [
                        "id",
                        "username",
                        "name",
                        "role"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "username": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "admin",
                            "user"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "getManagerMe",
        "parameters": []
      }
    },
    "/manager/logout": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Sair do Manager",
        "description": "Revoga somente o token de login atual; não revoga chave de API nem token global.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerLoginToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Operação concluída sem corpo"
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerLogout",
        "parameters": []
      }
    },
    "/manager/users": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Listar usuários do Manager",
        "description": "Somente administrador.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "users"
                  ],
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/ManagerUser"
                          },
                          {
                            "type": "object",
                            "required": [
                              "phones"
                            ],
                            "properties": {
                              "phones": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "getManagerUsers",
        "parameters": []
      },
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Criar usuário do Manager",
        "description": "Somente administrador. Cria usuário ativo com role user; admin é reservado e username é normalizado para minúsculas.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "username",
                  "name",
                  "password"
                ],
                "properties": {
                  "username": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "password": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 256,
                    "writeOnly": true
                  }
                }
              },
              "example": {
                "username": "operador.exemplo",
                "name": "Operador de exemplo",
                "password": "SUBSTITUA_POR_SENHA_FORTE"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagerUser"
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "409": {
            "description": "Nome de usuário já existe ou alteração concorrente"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerUsers",
        "parameters": []
      }
    },
    "/manager/users/{id}": {
      "patch": {
        "tags": [
          "Manager"
        ],
        "summary": "Atualizar usuário do Manager",
        "description": "Somente administrador. Desativar invalida a geração de login; logins anteriores não retornam após reativação. Chaves de API ficam suspensas enquanto desativado e retomam após reativação se não expiradas nem revogadas. Senhas usam hashes scrypt.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "writeOnly": true
                  },
                  "active": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "name": "Operador de exemplo",
                "active": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ManagerUser"
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "409": {
            "description": "Nome de usuário já existe ou alteração concorrente"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "patchManagerUsersId"
      }
    },
    "/manager/users/{id}/revoke-keys": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Revogar chaves de usuário",
        "description": "Somente administrador.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Operação concluída sem corpo"
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerUsersIdRevokeKeys"
      }
    },
    "/manager/assignments": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Consultar atribuições e histórico",
        "description": "Somente administrador. Retorna assignments (mapa por PN canônico) e history. Atribuição persistente existe antes da conexão e sobrevive à remoção; webhooks exigem restauração manual.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "assignments",
                    "history"
                  ],
                  "properties": {
                    "assignments": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    },
                    "history": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ManagerAssignmentEvent"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "getManagerAssignments",
        "parameters": []
      }
    },
    "/manager/assignments/{phone}": {
      "put": {
        "tags": [
          "Manager"
        ],
        "summary": "Atribuir, transferir ou liberar conta",
        "description": "Somente administrador. CAS compara expected_owner com o proprietário atual; null representa ausência de proprietário. user_id null libera a atribuição. Em conflito, revisar proprietário atualizado no diálogo e confirmar novamente, sem repetição automática.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "AdminToken": []
          }
        ],
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "user_id",
                  "expected_owner"
                ],
                "properties": {
                  "user_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "expected_owner": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "user_id": "ID_DO_NOVO_PROPRIETARIO",
                "expected_owner": null
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "409": {
            "description": "Proprietário alterado; revisar antes de tentar novamente",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "current_owner"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "current_owner": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "putManagerAssignmentsPhone"
      }
    },
    "/manager/keys": {
      "get": {
        "tags": [
          "Manager"
        ],
        "summary": "Listar próprias chaves",
        "description": "Somente chaves da conta autenticada; não aceita identidade escolhida pelo cliente. Exige token de login, não chave de API.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerLoginToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "keys"
                  ],
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ManagerKey"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "getManagerKeys",
        "parameters": []
      },
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Criar chave pessoal",
        "description": "Chave opaca aleatória, separada da senha. Pertence à conta autenticada. Validade padrão de 90 dias, máxima de 365 dias. Exige token de login, não chave de API.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerLoginToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "days": {
                    "type": "number",
                    "minimum": 0,
                    "exclusiveMinimum": true,
                    "maximum": 365,
                    "default": 90
                  }
                }
              },
              "example": {
                "name": "Integração de exemplo",
                "days": 90
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Operação concluída",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "token",
                    "key"
                  ],
                  "properties": {
                    "token": {
                      "type": "string",
                      "description": "Segredo retornado somente na criação; listagens não o retornam."
                    },
                    "key": {
                      "$ref": "#/components/schemas/ManagerKey"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerKeys",
        "parameters": []
      }
    },
    "/manager/keys/{id}": {
      "delete": {
        "tags": [
          "Manager"
        ],
        "summary": "Revogar própria chave",
        "description": "Somente chave pertencente à conta autenticada. Exige token de login, não chave de API.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerLoginToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Operação concluída sem corpo"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "deleteManagerKeysId"
      }
    },
    "/manager/password": {
      "post": {
        "tags": [
          "Manager"
        ],
        "summary": "Alterar própria senha",
        "description": "Verifica a senha atual e grava hash scrypt da nova senha. A chave pessoal não é a senha. Exige token de login, não chave de API.",
        "x-release-status": "local-not-deployed",
        "security": [
          {
            "ManagerLoginToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "current_password",
                  "password"
                ],
                "properties": {
                  "current_password": {
                    "type": "string",
                    "writeOnly": true
                  },
                  "password": {
                    "type": "string",
                    "writeOnly": true
                  }
                }
              },
              "example": {
                "current_password": "SENHA_ATUAL",
                "password": "NOVA_SENHA_FORTE"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Operação concluída sem corpo"
          },
          "400": {
            "description": "Entrada inválida"
          },
          "401": {
            "description": "Credencial inválida, expirada ou sem acesso efetivo"
          },
          "403": {
            "description": "Operação não autorizada para esta identidade"
          },
          "409": {
            "description": "Nome de usuário já existe ou alteração concorrente"
          },
          "503": {
            "description": "Persistência do Manager indisponível; acesso não concedido"
          }
        },
        "operationId": "postManagerPassword",
        "parameters": []
      }
    },
    "/admin/webhooks/history/{phone}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Consultar histórico de webhooks de mensagens",
        "description": "Exclusivo do token global UNOAPI_AUTH_TOKEN. Retorna até 20 versões por número, mesmo após remoção. URLs exibem somente a origem; tokens e cabeçalhos não são retornados. Não consulta nem reconecta o WhatsApp.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{5,20}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Histórico em ordem de arquivamento mais recente primeiro",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "snapshots"
                  ],
                  "properties": {
                    "snapshots": {
                      "type": "array",
                      "maxItems": 20,
                      "items": {
                        "$ref": "#/components/schemas/WebhookHistorySnapshot"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Número inválido"
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "503": {
            "description": "Histórico indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminWebhooksHistoryPhone",
        "x-source-route": "/admin/webhooks/history/:phone",
        "x-source-controller": "webhookHistoryController.handle"
      }
    },
    "/admin/webhooks/history/{phone}/restore": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Restaurar webhooks históricos como desativados",
        "description": "Exclusivo do token global. Exige sessão existente no mesmo servidor do snapshot. Mantém IDs e credenciais sem retorná-las. Não reconecta, não reenvia mensagens e não altera destinos centralizados de status. Conflitos exigem replace_existing=true. Alterações concorrentes retornam 409; a expiração da configuração é preservada.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{5,20}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "snapshot_id",
                  "webhook_ids"
                ],
                "properties": {
                  "snapshot_id": {
                    "type": "string"
                  },
                  "webhook_ids": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 200
                    }
                  },
                  "replace_existing": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seleção restaurada sem ativação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "restored",
                    "enabled"
                  ],
                  "properties": {
                    "restored": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "enabled": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Seleção inválida ou ID ausente/ambíguo no snapshot"
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "404": {
            "description": "Sessão ou snapshot não encontrado"
          },
          "409": {
            "description": "Conflito de ID",
            "servidor diferente ou configuração alterada durante a restauração": null
          },
          "503": {
            "description": "Histórico indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "postAdminWebhooksHistoryPhoneRestore",
        "x-source-route": "/admin/webhooks/history/:phone/restore",
        "x-source-controller": "webhookHistoryController.handle"
      }
    },
    "/admin/session-webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Listar destinos centralizados de eventos de sessão",
        "description": "Requer UNOAPI_AUTH_TOKEN global. Tokens de sessão não são aceitos. Segredos nunca são retornados.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Destinos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "destinations"
                  ],
                  "properties": {
                    "destinations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionWebhookDestination"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "503": {
            "description": "Persistência indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminSessionWebhooks",
        "x-source-route": "/admin/session-webhooks",
        "x-source-controller": "sessionWebhooksController.handle",
        "parameters": []
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Criar destino de eventos de sessão",
        "description": "Requer UNOAPI_AUTH_TOKEN global. Não altera os webhooks de mensagens.\nSessões atuais devem ser selecionadas explicitamente; a inclusão automática\nvale somente para sessões Zapo criadas posteriormente no servidor informado.\nLimite de 100 destinos e 1000 sessões por destino. Não há escopo de conta ViperChat implícito.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionWebhookDestinationInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Destino criado (sem segredos)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDestination"
                }
              }
            }
          },
          "400": {
            "description": "Contrato inválido ou sessão fora do servidor/provider suportado"
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "503": {
            "description": "Persistência indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "postAdminSessionWebhooks",
        "x-source-route": "/admin/session-webhooks",
        "x-source-controller": "sessionWebhooksController.handle",
        "parameters": []
      }
    },
    "/admin/session-webhooks/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "put": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Substituir configuração do destino",
        "description": "Requer token global. Campos não secretos são substituídos. Segredos omitidos são\npreservados; bearer_token vazio remove o Bearer. signing_secret é opcional; vazio remove HMAC,\nnão vazio deve ter pelo menos 32 caracteres.\nA alteração invalida entregas pendentes da revisão anterior para não redirecionar eventos antigos.\nDesligar inclusão futura não remove membros atuais se session_ids for preservado.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionWebhookDestinationInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Destino atualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDestination"
                }
              }
            }
          },
          "400": {
            "description": "Configuração inválida"
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "404": {
            "description": "Destino inexistente"
          },
          "503": {
            "description": "Persistência indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminSessionWebhooksId",
        "x-source-route": "/admin/session-webhooks/:id",
        "x-source-controller": "sessionWebhooksController.handle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Excluir destino e cancelar suas entregas pendentes",
        "description": "Requer token global. Não remove sessões nem altera seus webhooks de mensagens. Requisição HTTP já em andamento pode concluir.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "responses": {
          "204": {
            "description": "Destino removido"
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "404": {
            "description": "Destino inexistente"
          },
          "503": {
            "description": "Persistência indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminSessionWebhooksId",
        "x-source-route": "/admin/session-webhooks/:id",
        "x-source-controller": "sessionWebhooksController.handle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/session-webhooks/states": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Consultar últimas observações de estado",
        "description": "Requer token global. Retorna somente sessões já observadas pela versão com monitoramento,\nincluindo tombstones de remoção. Ausência não significa desconectada.\ndestination_id filtra pelos vínculos atuais; remoções já desvinculadas só aparecem na consulta sem filtro.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "parameters": [
          {
            "in": "query",
            "name": "destination_id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Últimas observações; destination_id vazio nos snapshots, preenchido apenas nas entregas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "states"
                  ],
                  "properties": {
                    "states": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionLifecycleEvent"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo requerido"
          },
          "404": {
            "description": "Destino inexistente"
          },
          "503": {
            "description": "Persistência indisponível"
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminSessionWebhooksStates",
        "x-source-route": "/admin/session-webhooks/states",
        "x-source-controller": "sessionWebhooksController.handle"
      }
    },
    "/ping": {
      "get": {
        "summary": "Verificar disponibilidade da API",
        "responses": {
          "200": {
            "description": "pong",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Sistema"
        ],
        "operationId": "getPing",
        "x-source-route": "/ping",
        "parameters": []
      }
    },
    "/version": {
      "get": {
        "summary": "Consultar versão instalada",
        "description": "A consulta ao GitHub é feita no servidor e armazenada em cache por 15 minutos.",
        "responses": {
          "200": {
            "description": "Estado de atualização do ViperConnect",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionStatus"
                }
              }
            }
          }
        },
        "tags": [
          "Sistema"
        ],
        "operationId": "getVersion",
        "x-source-route": "/version",
        "x-source-controller": "indexController.versionStatus",
        "parameters": []
      }
    },
    "/admin/rabbitmq/queues": {
      "get": {
        "tags": [
          "Administração"
        ],
        "summary": "Listar filas RabbitMQ da UnoAPI",
        "description": "Requer o token administrativo global (`UNOAPI_AUTH_TOKEN`). As credenciais são\nobtidas internamente de `AMQP_URL`; nenhuma credencial do RabbitMQ é recebida\nou devolvida por esta rota.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Filas cujo nome pertence ao namespace configurado da UnoAPI.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queues": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "messages": {
                            "type": "integer"
                          },
                          "messages_ready": {
                            "type": "integer"
                          },
                          "messages_unacknowledged": {
                            "type": "integer"
                          },
                          "consumers": {
                            "type": "integer"
                          },
                          "state": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminRabbitmqQueues",
        "x-source-route": "/admin/rabbitmq/queues",
        "x-source-controller": "queuesController.list",
        "parameters": []
      }
    },
    "/admin/rabbitmq/queues/{queue}/messages": {
      "parameters": [
        {
          "name": "queue",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Administração"
        ],
        "summary": "Inspecionar uma amostra de mensagens da fila",
        "description": "Lê até 50 mensagens e as recoloca na fila. A inspeção pode alterar a ordem\nrelativa das mensagens e nunca remove itens.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "parameters": [
          {
            "name": "queue",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "session",
            "in": "query",
            "description": "Filtra a amostra por telefone da sessão no routing key ou payload.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Amostra com campos sensíveis mascarados.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queue": {
                      "type": "string"
                    },
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou fila fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminRabbitmqQueuesQueueMessages",
        "x-source-route": "/admin/rabbitmq/queues/:queue/messages",
        "x-source-controller": "queuesController.preview"
      },
      "delete": {
        "tags": [
          "Administração"
        ],
        "summary": "Remover uma ou várias mensagens prontas",
        "description": "Remove as próximas 1 a 50 mensagens prontas ou todas quando `count` for `all`.\nMensagens já entregues a consumidores (unacked) não são removidas. Exige confirmação\nliteral do nome da fila.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "count",
                  "confirm"
                ],
                "properties": {
                  "count": {
                    "oneOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 50
                      },
                      {
                        "type": "string",
                        "enum": [
                          "all"
                        ]
                      }
                    ]
                  },
                  "confirm": {
                    "type": "string",
                    "description": "Nome exato da fila."
                  }
                }
              },
              "example": {
                "count": 1,
                "confirm": "SUBSTITUA_PELO_NOME_EXATO_DA_FILA"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da remoção.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queue": {
                      "type": "string"
                    },
                    "purged": {
                      "type": "boolean"
                    },
                    "removed": {
                      "oneOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "string",
                          "enum": [
                            "all"
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Confirmação inválida."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou fila fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminRabbitmqQueuesQueueMessages",
        "x-source-route": "/admin/rabbitmq/queues/:queue/messages",
        "x-source-controller": "queuesController.purge",
        "parameters": [
          {
            "name": "queue",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/redis/keys": {
      "get": {
        "tags": [
          "Administração"
        ],
        "summary": "Listar chaves Redis da UnoAPI",
        "description": "Usa SCAN e limita o resultado a 1000 chaves. Expõe os namespaces unoapi- e unoapi:, além das chaves permitidas users, names, assignments, history e keys de manager-identity:{v1}:. Tokens de login e índices de autenticação permanecem ocultos. Acesso: administrador autenticado (token global da stack ou login Manager com papel admin).",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Chaves encontradas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminRedisKeys",
        "x-source-route": "/admin/redis/keys",
        "x-source-controller": "redisAdminController.list"
      }
    },
    "/admin/redis/keys/{key}": {
      "parameters": [
        {
          "name": "key",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Administração"
        ],
        "summary": "Consultar tipo, TTL e conteúdo de uma chave",
        "description": "Limita coleções grandes e mascara campos sensíveis.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "responses": {
          "200": {
            "description": "Conteúdo tipado da chave.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "string",
                        "hash",
                        "list",
                        "set",
                        "zset",
                        "stream",
                        "none"
                      ]
                    },
                    "ttl": {
                      "type": "integer"
                    },
                    "size": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "readOnly": {
                      "type": "boolean",
                      "description": "Quando true, o conteúdo é uma projeção segura e não pode ser editado ou excluído pela API Redis, inclusive por subárvore. Identidades Manager e histórico de webhooks retornam true. Tentativas de escrita retornam HTTP 403 com redis_key_read_only."
                    },
                    "value": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou chave fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "getAdminRedisKeysKey",
        "x-source-route": "/admin/redis/keys/:key",
        "x-source-controller": "redisAdminController.get",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "put": {
        "tags": [
          "Administração"
        ],
        "summary": "Criar ou substituir uma chave",
        "description": "Aceita string, hash, list, set e zset. Exige confirmação literal da chave.\nConteúdo mascarado não pode ser salvo, evitando substituir segredos por `[REDACTED]`.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "value",
                  "confirm"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "string",
                      "hash",
                      "list",
                      "set",
                      "zset"
                    ]
                  },
                  "value": {},
                  "ttlSeconds": {
                    "type": "integer",
                    "description": "Use -1 para não expirar."
                  },
                  "confirm": {
                    "type": "string",
                    "description": "Nome exato da chave."
                  }
                }
              },
              "example": {
                "type": "string",
                "value": "exemplo",
                "ttlSeconds": 60,
                "confirm": "unoapi:exemplo:chave"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chave salva.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "saved": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Confirmação, tipo ou conteúdo inválido."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou chave fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "putAdminRedisKeysKey",
        "x-source-route": "/admin/redis/keys/:key",
        "x-source-controller": "redisAdminController.save",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "Administração"
        ],
        "summary": "Excluir uma chave",
        "description": "Exige confirmação literal do nome da chave.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "confirm": "unoapi:exemplo:chave"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quantidade de chaves removidas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Confirmação inválida."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou chave fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": true,
        "operationId": "deleteAdminRedisKeysKey",
        "x-source-route": "/admin/redis/keys/:key",
        "x-source-controller": "redisAdminController.remove",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/admin/redis/query": {
      "post": {
        "tags": [
          "Administração"
        ],
        "summary": "Executar consulta Redis segura",
        "description": "Aceita apenas SCAN, TYPE, TTL, GET, HGETALL, LRANGE, SMEMBERS e ZRANGE.\nComandos administrativos, escrita, scripts e chaves fora do namespace UnoAPI são bloqueados.\n\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "command"
                ],
                "properties": {
                  "command": {
                    "type": "string",
                    "enum": [
                      "SCAN",
                      "TYPE",
                      "TTL",
                      "GET",
                      "HGETALL",
                      "LRANGE",
                      "SMEMBERS",
                      "ZRANGE"
                    ]
                  },
                  "args": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "command": "SCAN",
                "args": [
                  "unoapi:exemplo:",
                  "20"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da consulta.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Comando não permitido."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Token administrativo global obrigatório ou chave fora do namespace permitido."
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "operationId": "postAdminRedisQuery",
        "x-source-route": "/admin/redis/query",
        "x-source-controller": "redisAdminController.query",
        "parameters": []
      }
    },
    "/sessions": {
      "get": {
        "summary": "Listar sessões",
        "responses": {
          "200": {
            "description": "Lista de conexões/sessões",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionsList"
                }
              }
            }
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "getSessions",
        "x-source-route": "/sessions",
        "x-source-controller": "phoneNumberController.list",
        "parameters": []
      }
    },
    "/sessions/{phone}": {
      "get": {
        "summary": "Abrir configuração e pareamento da sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "HTML com QR/Config da sessão",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "getSessionsPhone",
        "x-source-route": "/sessions/:phone",
        "x-source-controller": "sessionController.index"
      }
    },
    "/{version}/{phone}": {
      "get": {
        "summary": "Consultar estado e configuração da sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Informações da sessão e templates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneInfo"
                }
              }
            }
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "getVersionPhone",
        "x-source-route": "/:version/:phone",
        "x-source-controller": "phoneNumberController.get"
      }
    },
    "/{version}/{phone}/phone_numbers": {
      "get": {
        "summary": "Listar conexões da sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de configurações",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionsList"
                }
              }
            }
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "getVersionPhonePhoneNumbers",
        "x-source-route": "/:version/:phone/phone_numbers",
        "x-source-controller": "phoneNumberController.list"
      }
    },
    "/{version}/{phone}/templates": {
      "post": {
        "summary": "Consultar modelos de mensagem",
        "description": "Compatível com o API ViperConnect; neste projeto retorna a lista local/forward.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Templates disponíveis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Modelos de mensagem"
        ],
        "operationId": "postVersionPhoneTemplates",
        "x-source-route": "/:version/:phone/templates",
        "x-source-controller": "templatesController.templates"
      }
    },
    "/{version}/{phone}/messages": {
      "post": {
        "summary": "Enviar mensagem",
        "description": "- Em caso de falha de envio, a API responde 200 com corpo OK e o erro é enviado ao webhook de saída.\n- Para mensagens temporárias, informe `ttl` na raiz com o tempo de expiração em segundos.\n- A primeira URL ou domínio público válido gera prévia automaticamente; não é necessário definir uma flag no payload. Domínios sem protocolo são normalizados para `https://` antes do envio.\n- Para publicar Status/Stories, use o modelo específico com `to: status@broadcast`.\n- Mídias preservam o formato API ViperConnect por `link`. Como extensão ViperConnect, também podem usar `base64` puro ou Data URI; a UnoAPI persiste os bytes antes de enfileirar e nunca encaminha o Base64 ao RabbitMQ ou aos webhooks.\n- PDFs Oracle Reports legados são detectados e normalizados automaticamente antes do upload ao WhatsApp, tanto por `link` quanto por `base64`. O original permanece intacto; PDFs comuns, criptografados, assinados ou com formulário não são convertidos.\n",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageRequest"
              },
              "examples": {
                "text": {
                  "summary": "Texto com prévia automática de link",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "text",
                    "text": {
                      "body": "Conheça o ViperConnect: github.com/ViperTecCorporation/ViperConnect"
                    }
                  }
                },
                "expiringText": {
                  "summary": "Texto temporário",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "text",
                    "ttl": 86400,
                    "text": {
                      "body": "Esta mensagem expira em 24 horas."
                    }
                  }
                },
                "location": {
                  "summary": "Localização estática (formato API ViperConnect)",
                  "value": {
                    "messaging_product": "whatsapp",
                    "recipient_type": "individual",
                    "to": "5511999999999",
                    "type": "location",
                    "location": {
                      "latitude": -15.601,
                      "longitude": -56.0974,
                      "name": "Praça em Cuiabá",
                      "address": "Cuiabá, MT"
                    }
                  }
                },
                "textGroupMentionAll": {
                  "summary": "Texto em grupo com @all/@todos",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "120363012345678@g.us",
                    "type": "text",
                    "text": {
                      "body": "Aviso @todos"
                    }
                  }
                },
                "textGroupMentions": {
                  "summary": "Texto em grupo com @telefone",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "120363012345678@g.us",
                    "type": "text",
                    "text": {
                      "body": "Oi @5511999999999 e @5511888888888"
                    }
                  }
                },
                "messageEdit": {
                  "summary": "Editar mensagem enviada",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "message_edit",
                    "context": {
                      "message_id": "uno-message-id-original"
                    },
                    "text": {
                      "body": "Texto editado"
                    }
                  }
                },
                "image": {
                  "summary": "Imagem por link",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "image",
                    "image": {
                      "link": "https://exemplo.com/imagem.jpg",
                      "caption": "Legenda opcional"
                    }
                  }
                },
                "imageBase64": {
                  "summary": "Imagem por Base64 (extensão ViperConnect)",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "image",
                    "image": {
                      "base64": "/9j/4AAQSkZJRgABAQ...",
                      "mime_type": "image/jpeg",
                      "filename": "foto.jpg",
                      "caption": "Legenda opcional"
                    }
                  }
                },
                "imageViewOnce": {
                  "summary": "Imagem de visualização única (Zapo)",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "image",
                    "image": {
                      "link": "https://exemplo.com/imagem.jpg",
                      "view_once": true
                    }
                  }
                },
                "document": {
                  "summary": "Documento",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "document",
                    "document": {
                      "link": "https://exemplo.com/arquivo.pdf",
                      "filename": "contrato.pdf",
                      "caption": "Contrato para conferência",
                      "mime_type": "application/pdf"
                    }
                  }
                },
                "audio": {
                  "summary": "Mensagem de voz",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "audio",
                    "audio": {
                      "link": "https://exemplo.com/audio.ogg",
                      "mime_type": "audio/ogg",
                      "ptt": true
                    }
                  }
                },
                "video": {
                  "summary": "Vídeo",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "video",
                    "video": {
                      "link": "https://exemplo.com/video.mp4",
                      "caption": "Vídeo curto"
                    }
                  }
                },
                "statusImage": {
                  "summary": "Status/Story com imagem",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "status@broadcast",
                    "type": "image",
                    "image": {
                      "link": "https://vipertec.com.br/_content/ViperERP/img/FullCam08.jpg",
                      "caption": "Novidade"
                    },
                    "statusJidList": [
                      "5511999999999",
                      "5500000000002"
                    ]
                  }
                },
                "contacts": {
                  "summary": "Contatos (vCard simplificado)",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "contacts",
                    "contacts": [
                      {
                        "name": {
                          "formatted_name": "Contato Exemplo"
                        },
                        "phones": [
                          {
                            "wa_id": "5500000000002",
                            "phone": "+55 00 00000-0002"
                          }
                        ]
                      }
                    ]
                  }
                },
                "reaction": {
                  "summary": "Reação",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "reaction",
                    "reaction": {
                      "message_id": "MESSAGE_ID",
                      "emoji": "👍"
                    }
                  }
                },
                "poll": {
                  "summary": "Enquete",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "poll",
                    "poll": {
                      "name": "Qual plano você prefere?",
                      "options": [
                        "Básico",
                        "Profissional"
                      ],
                      "selectable_count": 1,
                      "allow_add_option": false
                    }
                  }
                },
                "pollVote": {
                  "summary": "Votar em uma enquete",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "poll_vote",
                    "poll_vote": {
                      "message_id": "MESSAGE_ID_DA_ENQUETE",
                      "selected_options": [
                        "Profissional"
                      ]
                    }
                  }
                },
                "sticker": {
                  "summary": "Figurinha",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "sticker",
                    "sticker": {
                      "link": "https://example.com/sticker.png"
                    }
                  }
                },
                "interactiveButtons": {
                  "summary": "Interativo - Botões",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "body": {
                        "text": "Escolha uma opção"
                      },
                      "action": {
                        "buttons": [
                          {
                            "type": "reply",
                            "reply": {
                              "id": "btn_1",
                              "title": "Opção 1"
                            }
                          },
                          {
                            "type": "reply",
                            "reply": {
                              "id": "btn_2",
                              "title": "Opção 2"
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "interactiveCtaButtons": {
                  "summary": "Interativo - Botões CTA (URL, ligação e copiar)",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5500000000001",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "body": {
                        "text": "Acesse ou fale com a equipe"
                      },
                      "action": {
                        "buttons": [
                          {
                            "type": "cta_url",
                            "url": {
                              "title": "Abrir site",
                              "link": "https://facebook.com.br"
                            }
                          },
                          {
                            "type": "cta_call",
                            "call": {
                              "title": "Ligar",
                              "phone_number": "+5511999999999"
                            }
                          },
                          {
                            "type": "cta_copy",
                            "copy_code": {
                              "title": "ChavePix",
                              "code": "0000000055442"
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "interactiveWebview": {
                  "summary": "Interativo - WebView Zapo (validado no lab em 03/10/2026)",
                  "description": "Abertura dentro do WhatsApp confirmada pelo usuario no iPhone em conversa individual e no Android em testes enviados a dois grupos, usando full e true com https://vipertec.com.br. Versoes de sistema e aplicativo nao registradas. Nao garante todos os clientes, carrosseis ou callback de formulario; delivered sozinho nao prova WebView.",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "body": {
                        "text": "Abra o formulario pelo botao."
                      },
                      "action": {
                        "buttons": [
                          {
                            "type": "cta_url",
                            "url": {
                              "title": "Abrir formulario",
                              "link": "https://example.com/form",
                              "webview_presentation": "full",
                              "webview_interaction": true
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "interactiveList": {
                  "summary": "Interativo - Lista",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "list",
                      "header": {
                        "type": "text",
                        "text": "Menu"
                      },
                      "body": {
                        "text": "Escolha uma opção"
                      },
                      "footer": {
                        "text": "Unoapi"
                      },
                      "action": {
                        "button": "Ver opções",
                        "sections": [
                          {
                            "title": "Planos",
                            "rows": [
                              {
                                "id": "plan_basic",
                                "title": "Básico",
                                "description": "R$ 10"
                              },
                              {
                                "id": "plan_pro",
                                "title": "Pro",
                                "description": "R$ 20"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                },
                "interactiveCarousel": {
                  "summary": "Interativo - Carrossel com imagens e botões",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "carousel",
                      "body": {
                        "text": "Conheça nossos planos"
                      },
                      "action": {
                        "carousel": {
                          "cards": [
                            {
                              "header": {
                                "type": "image",
                                "image": {
                                  "link": "https://vipertec.com.br/_content/ViperERP/img/FullCam08.jpg"
                                }
                              },
                              "body": {
                                "text": "Plano Básico"
                              },
                              "footer": {
                                "text": "Para começar"
                              },
                              "action": {
                                "buttons": [
                                  {
                                    "type": "reply",
                                    "reply": {
                                      "id": "plan_basic",
                                      "title": "Escolher"
                                    }
                                  }
                                ]
                              }
                            },
                            {
                              "header": {
                                "type": "image",
                                "image": {
                                  "link": "https://vipertec.com.br/_content/ViperERP/img/FullCam08.jpg"
                                }
                              },
                              "body": {
                                "text": "Plano Profissional"
                              },
                              "footer": {
                                "text": "Mais recursos"
                              },
                              "action": {
                                "buttons": [
                                  {
                                    "type": "cta_url",
                                    "url": {
                                      "title": "Ver detalhes",
                                      "link": "https://vipertec.com.br"
                                    }
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "paymentPixStatic": {
                  "summary": "Pagamento - PIX estático",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "button",
                      "action": {
                        "buttons": [
                          {
                            "type": "payment_request",
                            "payment_setting": {
                              "type": "pix_static_code",
                              "pix_static_code": {
                                "merchant_name": "Minha Empresa",
                                "key": "financeiro@minhaempresa.com.br",
                                "key_type": "EMAIL"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "paymentPixDynamicStandalone": {
                  "summary": "PIX dinâmico avulso - fluxo simplificado oficial",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "body": {
                        "text": "Pague R$ 149,90 via PIX"
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "cobranca-14990",
                          "type": "digital-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "pix_dynamic_code",
                              "pix_dynamic_code": {
                                "code": "000201010212...",
                                "merchant_name": "Minha Empresa",
                                "key": "12345678000199",
                                "key_type": "CNPJ"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 14990,
                            "offset": 100
                          }
                        }
                      }
                    }
                  }
                },
                "orderPixDynamic": {
                  "summary": "Pedido com imagem e PIX dinâmico",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "header": {
                        "type": "image",
                        "image": {
                          "link": "https://vipertec.com.br/_content/ViperERP/img/FullCam08.jpg"
                        }
                      },
                      "body": {
                        "text": "Revise e pague seu pedido"
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "pedido-123",
                          "type": "physical-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "pix_dynamic_code",
                              "pix_dynamic_code": {
                                "code": "000201010212...",
                                "merchant_name": "Minha Empresa",
                                "key": "12345678000199",
                                "key_type": "CNPJ"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 50000,
                            "offset": 100
                          },
                          "order": {
                            "status": "pending",
                            "tax": {
                              "value": 0,
                              "offset": 100,
                              "description": "Sem impostos adicionais"
                            },
                            "items": [
                              {
                                "retailer_id": "produto-1",
                                "name": "Produto",
                                "amount": {
                                  "value": 50000,
                                  "offset": 100
                                },
                                "quantity": 1
                              }
                            ],
                            "subtotal": {
                              "value": 50000,
                              "offset": 100
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "orderPaymentLink": {
                  "summary": "Pedido simplificado com link de pagamento",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "body": {
                        "text": "Finalize seu pagamento"
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "pedido-124",
                          "type": "digital-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "payment_link",
                              "payment_link": {
                                "uri": "https://pagamentos.example.com/pedido-124"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 1500,
                            "offset": 100
                          }
                        }
                      }
                    }
                  }
                },
                "orderBoletoStandalone": {
                  "summary": "Boleto avulso - fluxo simplificado oficial",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "body": {
                        "text": "Pague o boleto de R$ 88,48"
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "boleto-8848",
                          "type": "digital-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "boleto",
                              "boleto": {
                                "digitable_line": "03399026944140000002628346101018898510000008848"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 8848,
                            "offset": 100
                          }
                        }
                      }
                    }
                  }
                },
                "orderOneClickStandalone": {
                  "summary": "Cartão em um clique - fluxo simplificado oficial",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "body": {
                        "text": "Confirme o pagamento de R$ 149,90"
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "cartao-14990",
                          "type": "digital-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "offsite_card_pay",
                              "offsite_card_pay": {
                                "last_four_digits": "5235",
                                "credential_id": "credencial-123"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 14990,
                            "offset": 100
                          }
                        }
                      }
                    }
                  }
                },
                "subscriptionBoletoPix": {
                  "summary": "Pedido real com boleto, PIX dinâmico e imagem",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_details",
                      "header": {
                        "type": "image",
                        "image": {
                          "link": "https://vipertec.com.br/_content/ViperERP/img/FullCam08.jpg"
                        }
                      },
                      "body": {
                        "text": "Boleto nº 1033239253 referente à assinatura de Câmera Comodato Mensal — 1 unidade. Vencimento: 10/07/2026. Valor: R$ 60,00."
                      },
                      "action": {
                        "name": "review_and_pay",
                        "parameters": {
                          "reference_id": "boleto-1033239253",
                          "type": "digital-goods",
                          "payment_type": "br",
                          "payment_settings": [
                            {
                              "type": "boleto",
                              "boleto": {
                                "digitable_line": "36490000920005525230800000010918900000000006000"
                              }
                            },
                            {
                              "type": "pix_dynamic_code",
                              "pix_dynamic_code": {
                                "code": "00020101021226940014BR.GOV.BCB.PIX2572qrcodespix.sejaefi.com.br/bolix/v2/cobv/663b44b6c993415e9e09f92c106d48865204000053039865802BR5905EFISA6008SAOPAULO62070503***63047595",
                                "merchant_name": "EFISA",
                                "key": "663b44b6c993415e9e09f92c106d4886",
                                "key_type": "EVP"
                              }
                            }
                          ],
                          "currency": "BRL",
                          "total_amount": {
                            "value": 6000,
                            "offset": 100
                          },
                          "order": {
                            "status": "pending",
                            "tax": {
                              "value": 0,
                              "offset": 100,
                              "description": "Sem impostos adicionais"
                            },
                            "items": [
                              {
                                "retailer_id": "camera-comodato-mensal",
                                "name": "Câmera Comodato Mensal",
                                "amount": {
                                  "value": 6000,
                                  "offset": 100
                                },
                                "quantity": 1
                              }
                            ],
                            "subtotal": {
                              "value": 6000,
                              "offset": 100
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "orderStatus": {
                  "summary": "Confirmar pagamento e manter pedido em processamento",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_status",
                      "body": {
                        "text": "Pagamento confirmado para o boleto nº 1033239253."
                      },
                      "footer": {
                        "text": "Assinatura confirmada"
                      },
                      "action": {
                        "name": "review_order",
                        "parameters": {
                          "reference_id": "boleto-1033239253",
                          "order": {
                            "status": "processing",
                            "description": "Pagamento confirmado. Pedido em preparação."
                          },
                          "payment": {
                            "status": "captured",
                            "timestamp": 1785125734
                          }
                        }
                      }
                    }
                  }
                },
                "orderCompleted": {
                  "summary": "Concluir pedido já pago",
                  "value": {
                    "messaging_product": "whatsapp",
                    "to": "5511999999999",
                    "type": "interactive",
                    "interactive": {
                      "type": "order_status",
                      "body": {
                        "text": "Pedido concluído."
                      },
                      "action": {
                        "name": "review_order",
                        "parameters": {
                          "reference_id": "boleto-1033239253",
                          "order": {
                            "status": "completed",
                            "description": "Pagamento confirmado e pedido concluído."
                          },
                          "payment": {
                            "status": "captured",
                            "timestamp": 1785125734
                          }
                        }
                      }
                    }
                  }
                },
                "markAsRead": {
                  "summary": "Marcar mensagem como lida",
                  "value": {
                    "status": "read",
                    "message_id": "MESSAGE_ID"
                  }
                },
                "deleteMessage": {
                  "summary": "Apagar mensagem enviada",
                  "value": {
                    "status": "deleted",
                    "message_id": "MESSAGE_ID"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro de validação",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error400"
                }
              }
            }
          }
        },
        "tags": [
          "Mensagens"
        ],
        "operationId": "postVersionPhoneMessages",
        "x-source-route": "/:version/:phone/messages",
        "x-source-controller": "messagesController.index"
      }
    },
    "/{version}/{phone}/marketing_messages": {
      "post": {
        "summary": "Enviar mensagem de marketing",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          }
        },
        "tags": [
          "Mensagens"
        ],
        "operationId": "postVersionPhoneMarketingMessages",
        "x-source-route": "/:version/:phone/marketing_messages",
        "x-source-controller": "marketingMessagesController.index"
      }
    },
    "/{version}/{phone}/preflight/status": {
      "post": {
        "summary": "Validar destinatário antes do envio",
        "description": "Verifica sessão online e se destinatários existem no WhatsApp.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreflightStatusRequest"
              },
              "example": {
                "statusJidList": [
                  "5511999999999",
                  "5500000000002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da verificação",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreflightStatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erro na verificação",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error400"
                }
              }
            }
          }
        },
        "tags": [
          "Mensagens"
        ],
        "operationId": "postVersionPhonePreflightStatus",
        "x-source-route": "/:version/:phone/preflight/status",
        "x-source-controller": "preflightController.status"
      }
    },
    "/{version}/{phone}/groups": {
      "get": {
        "summary": "Listar grupos da sessão",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Deslocamento devolvido em paging.cursors.after pela página anterior"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Pesquisa por nome ou JID do grupo"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de grupos em cache",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupsListResponse"
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "getVersionPhoneGroups",
        "x-source-route": "/:version/:phone/groups",
        "x-source-controller": "groupsController.list"
      },
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Criar grupo",
        "description": "Operação exposta pelo controller `groupsController.create` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneGroups",
        "x-source-route": "/:version/:phone/groups",
        "x-source-controller": "groupsController.create"
      }
    },
    "/{version}/{phone}/groups/{groupId}": {
      "get": {
        "summary": "Consultar detalhes do grupo",
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "$ref": "#/components/parameters/GroupIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Metadata normalizado do grupo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupDetailsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Grupo não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error400"
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "getVersionPhoneGroupsGroupId",
        "x-source-route": "/:version/:phone/groups/:groupId",
        "x-source-controller": "groupsController.details"
      },
      "patch": {
        "summary": "Atualizar configurações do grupo",
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "$ref": "#/components/parameters/GroupIdPath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupSettingsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configurações aplicadas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupSettingsResponse"
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "patchVersionPhoneGroupsGroupId",
        "x-source-route": "/:version/:phone/groups/:groupId",
        "x-source-controller": "groupsController.update"
      },
      "delete": {
        "summary": "Sair do grupo",
        "parameters": [
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "$ref": "#/components/parameters/GroupIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Sessão removida do grupo",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "group_id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "deleteVersionPhoneGroupsGroupId",
        "x-source-route": "/:version/:phone/groups/:groupId",
        "x-source-controller": "groupsController.destroy"
      },
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Atualizar dados do grupo",
        "description": "Operação exposta pelo controller `groupsController.update` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneGroupsGroupId",
        "x-source-route": "/:version/:phone/groups/:groupId",
        "x-source-controller": "groupsController.update"
      }
    },
    "/{version}/{phone}/groups/{groupId}/participants": {
      "get": {
        "summary": "Listar participantes do grupo",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "groupId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Aceita 1203... ou 1203...@g.us"
          }
        ],
        "responses": {
          "200": {
            "description": "Participantes do grupo em cache",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupParticipantsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Grupo não encontrado em cache",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error400"
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "getVersionPhoneGroupsGroupIdParticipants",
        "x-source-route": "/:version/:phone/groups/:groupId/participants",
        "x-source-controller": "groupsController.participants"
      },
      "patch": {
        "summary": "Promover ou rebaixar administradores do grupo",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "groupId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Aceita 1203... ou 1203...@g.us"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action",
                  "participants"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "promote",
                      "demote"
                    ]
                  },
                  "participants": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "oneOf": [
                        {
                          "type": "string",
                          "description": "Número, PN JID ou LID"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "wa_id": {
                              "type": "string"
                            },
                            "user_id": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Participantes promovidos ou rebaixados",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "group_id",
                    "failed"
                  ],
                  "properties": {
                    "group_id": {
                      "type": "string"
                    },
                    "promoted": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "demoted": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "failed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ação ou participantes inválidos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error400"
                }
              }
            }
          }
        },
        "tags": [
          "Grupos"
        ],
        "operationId": "patchVersionPhoneGroupsGroupIdParticipants",
        "x-source-route": "/:version/:phone/groups/:groupId/participants",
        "x-source-controller": "groupsController.updateParticipantRoles"
      },
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Adicionar participantes ao grupo",
        "description": "Operação exposta pelo controller `groupsController.addParticipants` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneGroupsGroupIdParticipants",
        "x-source-route": "/:version/:phone/groups/:groupId/participants",
        "x-source-controller": "groupsController.addParticipants"
      },
      "delete": {
        "tags": [
          "Grupos"
        ],
        "summary": "Remover participantes do grupo",
        "description": "Operação exposta pelo controller `groupsController.removeParticipants` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "deleteVersionPhoneGroupsGroupIdParticipants",
        "x-source-route": "/:version/:phone/groups/:groupId/participants",
        "x-source-controller": "groupsController.removeParticipants"
      }
    },
    "/{version}/{phone}/{media_id}": {
      "get": {
        "summary": "Consultar metadados de uma mídia",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "media_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dados da mídia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaResponse"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado"
          }
        },
        "tags": [
          "Mídia"
        ],
        "operationId": "getVersionPhoneMediaId",
        "x-source-route": "/:version/:phone/:media_id",
        "x-source-controller": "mediaController.index"
      }
    },
    "/{version}/download/{phone}/{file}": {
      "get": {
        "summary": "Baixar arquivo de mídia",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "file",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Arquivo binário",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "Não encontrado"
          }
        },
        "tags": [
          "Mídia"
        ],
        "operationId": "getVersionDownloadPhoneFile",
        "x-source-route": "/:version/download/:phone/:file",
        "x-source-controller": "mediaController.download"
      }
    },
    "/{version}/{session}/profile-pictures/{picture_id}": {
      "get": {
        "tags": [
          "Mídia"
        ],
        "operationId": "getVersionSessionProfilePicturesPictureId",
        "summary": "Baixar foto de perfil pelo ID estável",
        "description": "Transmite a imagem armazenada internamente sem redirecionar para MinIO, S3 ou R2.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "in": "path",
            "name": "session",
            "required": true,
            "description": "Telefone da sessão, ID ViperConnect ou alias existente.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "picture_id",
            "required": true,
            "description": "PN, LID ou JID de grupo.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "If-None-Match",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Imagem de perfil",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "Last-Modified": {
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/gif": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "304": {
            "description": "Foto não modificada"
          },
          "400": {
            "description": "Identificador inválido"
          },
          "401": {
            "description": "Token ausente"
          },
          "404": {
            "description": "Foto não encontrada"
          },
          "413": {
            "description": "Foto acima do limite permitido"
          },
          "415": {
            "description": "Objeto não é uma imagem suportada"
          }
        }
      }
    },
    "/{phone}/contacts": {
      "get": {
        "summary": "Listar contatos armazenados",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "default": "0"
            },
            "description": "Cursor Redis devolvido em next_cursor pela página anterior"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            }
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Pesquisa por nome, telefone, username ou LID"
          }
        ],
        "responses": {
          "200": {
            "description": "Página do diretório de contatos sincronizado pela Zapo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDirectoryResponse"
                }
              }
            }
          },
          "409": {
            "description": "A sessão não utiliza o provider Zapo"
          }
        },
        "tags": [
          "Contatos"
        ],
        "operationId": "getPhoneContacts",
        "x-source-route": "/:phone/contacts",
        "x-source-controller": "contactsController.get"
      },
      "post": {
        "summary": "Verificar números no diretório de contatos",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactsRequest"
              },
              "example": {
                "blocking": "no_wait",
                "force_check": true,
                "contacts": [
                  "5500000000002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado de validação",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactsResponse"
                }
              }
            }
          }
        },
        "tags": [
          "Contatos"
        ],
        "operationId": "postPhoneContacts",
        "x-source-route": "/:phone/contacts",
        "x-source-controller": "contactsController.post"
      }
    },
    "/{phone}/contacts/import": {
      "post": {
        "summary": "Adicionar ou atualizar contato na agenda do WhatsApp",
        "description": "Salva o contato na agenda sincronizada da sessão por meio da mutação\noficial de app-state `Contact` da Zapo. A operação é idempotente para\no mesmo número.\n\nQuando `user_id` é informado, ele deve ser um LID e tem prioridade para\nlocalizar no store da Zapo o PN exato usado no envelope do WhatsApp.\nSem `user_id`, a própria Zapo resolve o número para LID antes de salvar.\nA normalização brasileira de apresentação não é aplicada ao PN enviado\nao provider.\n",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactImportRequest"
              },
              "examples": {
                "phoneOnly": {
                  "summary": "Resolver o LID e adicionar o contato",
                  "value": {
                    "phone_number": "5500000000002",
                    "full_name": "Contato Exemplo",
                    "first_name": "Contato"
                  }
                },
                "lidFirst": {
                  "summary": "Usar a identidade LID já conhecida pela aplicação",
                  "value": {
                    "phone_number": "5500000000002",
                    "user_id": "000000000000002@lid",
                    "full_name": "Contato Exemplo",
                    "first_name": "Contato",
                    "username": "contato_exemplo"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contato salvo; retorna a identidade canônica usada pela Zapo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactImportResponse"
                }
              }
            }
          },
          "400": {
            "description": "Número, nome, LID ou username inválido"
          },
          "404": {
            "description": "Não foi possível resolver o LID ou o PN exato no store Zapo"
          },
          "409": {
            "description": "Sessão indisponível, desconectada ou pertencente a outro worker"
          }
        },
        "tags": [
          "Contatos"
        ],
        "operationId": "postPhoneContactsImport",
        "x-source-route": "/:phone/contacts/import",
        "x-source-controller": "contactsController.save"
      }
    },
    "/{phone}/blacklist/{webhook_id}": {
      "post": {
        "summary": "Adicionar número à lista de bloqueio do webhook",
        "description": "Bloqueia somente o encaminhamento ao webhook. Telefone e LID são equivalentes quando\nseu vínculo está no store da própria sessão; adicionar/remover qualquer variante afeta ambas.\nSem vínculo conhecido, somente a identidade informada é tratada. Grupos @g.us são\nindependentes dos participantes. Chaves antigas continuam consultadas nos próximos eventos.\nA resposta confirma enfileiramento, não aplicação imediata, em instalações com AMQP.\n",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "webhook_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "Telefone, JID @s.whatsapp.net, LID completo @lid ou grupo completo @g.us."
                  },
                  "ttl": {
                    "type": "integer",
                    "description": "Segundos. Positivo expira; negativo persiste; zero ou omitido remove o bloqueio e aliases conhecidos."
                  }
                }
              },
              "example": {
                "to": "5511999999999",
                "ttl": 86400
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parâmetros inválidos"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "operationId": "postPhoneBlacklistWebhookId",
        "x-source-route": "/:phone/blacklist/:webhook_id",
        "x-source-controller": "blacklistController.update"
      }
    },
    "/{phone}/request_code": {
      "post": {
        "summary": "Solicitar código de pareamento",
        "description": "Solicita um pairing code ao motor da sessão. No motor Zapo, a resposta HTTP contém o código puro e o Socket.IO também publica uma imagem com o código legível pelo contrato compatível `broadcast`, usando `type: qrcode`. A aplicação pode continuar exibindo `content` em uma tag `img`, sem criar um evento específico para pairing code.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "code": {
                      "type": "string",
                      "description": "Código temporário que deve ser digitado no WhatsApp."
                    }
                  },
                  "example": {
                    "success": true,
                    "code": "1234-5678"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Pareamento"
        ],
        "operationId": "postPhoneRequestCode",
        "x-source-route": "/:phone/request_code",
        "x-source-controller": "pairingCodeController.request"
      }
    },
    "/timer/{phone}/{to}": {
      "post": {
        "summary": "Iniciar timer de mensagem automática",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "to",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "message",
                  "timeout"
                ],
                "properties": {
                  "message": {
                    "type": "string"
                  },
                  "timeout": {
                    "type": "integer",
                    "description": "Tempo de espera em ms"
                  }
                }
              },
              "example": {
                "message": "Ainda precisamos da sua resposta",
                "timeout": 300000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Parâmetros ausentes"
          }
        },
        "tags": [
          "Mensagens"
        ],
        "operationId": "postTimerPhoneTo",
        "x-source-route": "/timer/:phone/:to",
        "x-source-controller": "timerController.start"
      },
      "delete": {
        "summary": "Cancelar timer de mensagem automática",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "path",
            "name": "to",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "tags": [
          "Mensagens"
        ],
        "operationId": "deleteTimerPhoneTo",
        "x-source-route": "/timer/:phone/:to",
        "x-source-controller": "timerController.stop"
      }
    },
    "/{version}/{phone}/register": {
      "post": {
        "summary": "Registrar ou atualizar uma sessão",
        "description": "Em mobile primary, preserva credenciais, ativa autoConnect e solicita reconexão sem QR/SMS enquanto o registro for válido. Webhooks recebidos são adicionados ou atualizados por ID antes da reconexão; destinos omitidos permanecem. Sem webhooks no corpo, preserva os existentes. HTTP 200 não confirma conexão online.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterConfig"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração aplicada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterConfig"
                }
              }
            }
          },
          "400": {
            "description": "Erro ao aplicar configuração"
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "postVersionPhoneRegister",
        "x-source-route": "/:version/:phone/register",
        "x-source-controller": "registrationController.register"
      }
    },
    "/{version}/{phone}/deregister": {
      "post": {
        "summary": "Desconectar e remover uma sessão",
        "description": "Sessões comuns mantêm logout e remoção. Em mobile primary aceita corpo vazio, remove todos os webhooks ativos, encaminha a configuração anterior ao histórico, desativa autoConnect e desconecta sem logout nem limpeza de credenciais ou filas. Falhas de arquivamento são registradas em log sem bloquear a operação. Reconectar não restaura destinos automaticamente. HTTP 204 confirma publicação, não conclusão da desconexão. Register ou Conectar no painel retoma a sessão. Mensagens durante o período offline dependem da recuperação disponibilizada pelo WhatsApp.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Prefixo de compatibilidade da rota. Exemplos: `v15`, `v22` ou `v25`.",
            "schema": {
              "type": "string",
              "example": "v25"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {}
            }
          }
        },
        "responses": {
          "204": {
            "description": "Sem conteúdo"
          },
          "503": {
            "description": "Publicação falhou; suspensão pode já estar persistida. Repita a operação."
          }
        },
        "tags": [
          "Sessões"
        ],
        "operationId": "postVersionPhoneDeregister",
        "x-source-route": "/:version/:phone/deregister",
        "x-source-controller": "registrationController.deregister"
      }
    },
    "/webhooks/whatsapp/{phone}": {
      "get": {
        "summary": "Validar assinatura do webhook",
        "security": [],
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          },
          {
            "in": "query",
            "name": "hub.mode",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "hub.verify_token",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "hub.challenge",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Retorna o challenge",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Token inválido"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhooksWhatsappPhone",
        "x-source-route": "/webhooks/whatsapp/:phone",
        "x-source-controller": "webhookController.whatsappVerify"
      },
      "post": {
        "summary": "Receber evento encaminhado pelo webhook",
        "security": [],
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WebhookInbound"
                  },
                  {
                    "$ref": "#/components/schemas/WebhookAck"
                  },
                  {
                    "$ref": "#/components/schemas/WebhookStatusFailed"
                  },
                  {
                    "type": "object"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "example": {
                    "success": true
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Webhooks"
        ],
        "operationId": "postWebhooksWhatsappPhone",
        "x-source-route": "/webhooks/whatsapp/:phone",
        "x-source-controller": "webhookController.whatsapp"
      }
    },
    "/webhooks/fake/{phone}": {
      "post": {
        "summary": "Enviar evento de webhook para teste",
        "description": "Recebe qualquer payload e responde `{ \"success\": true }`.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PhonePath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WebhookStatusFailed"
                  },
                  {
                    "$ref": "#/components/schemas/WebhookInbound"
                  },
                  {
                    "$ref": "#/components/schemas/WebhookAck"
                  },
                  {
                    "type": "object"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "example": {
                    "success": true
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Webhooks"
        ],
        "operationId": "postWebhooksFakePhone",
        "x-source-route": "/webhooks/fake/:phone",
        "x-source-controller": "webhookFakeController.fake"
      }
    },
    "/admin/voip/bootstrap": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Estado agregado da telefonia",
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Usuário recebe apenas inventário filtrado e capacidades. Não retorna configuração global ou credenciais compartilhadas. Usuário Manager somente com Uno + VoIP compatíveis: upstream capabilities.managerSessionHistoryScope=1. Upstream antigo/incompatível mantém history=false e recordings=false; acesso negado sem fallback global. Credencial e escopo são resolvidos no servidor, não por headers enviados pelo cliente.",
        "responses": {
          "200": {
            "description": "Estado usado pela página Telefonia do Manager.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VoipBootstrap"
                    },
                    {
                      "$ref": "#/components/schemas/ManagerVoipBootstrap"
                    }
                  ]
                },
                "examples": {
                  "usuario": {
                    "summary": "Serviço VoIP com escopo de histórico compatível",
                    "value": {
                      "capabilities": {
                        "scoped": true,
                        "activeCalls": true,
                        "callCommands": true,
                        "createCalls": false,
                        "history": true,
                        "recordings": true,
                        "configuration": false,
                        "lines": true,
                        "automaticExtensions": true,
                        "extensionCredentials": true,
                        "disconnectRegistration": false,
                        "extensionSipMode": true,
                        "basicInboundSettings": false
                      },
                      "accounts": [],
                      "sessions": [],
                      "extensions": [],
                      "zapoLines": [],
                      "bridges": [],
                      "calls": []
                    }
                  },
                  "upstreamLegado": {
                    "summary": "Upstream antigo: histórico e gravações bloqueados",
                    "value": {
                      "capabilities": {
                        "scoped": true,
                        "activeCalls": true,
                        "callCommands": true,
                        "createCalls": false,
                        "history": false,
                        "recordings": false,
                        "configuration": false,
                        "lines": true,
                        "automaticExtensions": true,
                        "extensionCredentials": true,
                        "disconnectRegistration": false,
                        "extensionSipMode": true,
                        "basicInboundSettings": false
                      },
                      "accounts": [],
                      "sessions": [],
                      "extensions": [],
                      "zapoLines": [],
                      "bridges": [],
                      "calls": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Serviço VoIP não configurado."
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "operationId": "getAdminVoipBootstrap",
        "x-source-route": "/admin/voip/bootstrap",
        "x-source-controller": "voipController.bootstrap",
        "parameters": []
      }
    },
    "/admin/voip/calls": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar chamadas ativas",
        "responses": {
          "200": {
            "description": "Chamadas isoladas por sessão e callId.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "calls": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipCall"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Usuário vê apenas chamadas ativas das sessões atribuídas.",
        "operationId": "getAdminVoipCalls",
        "x-source-route": "/admin/voip/calls",
        "x-source-controller": "voipController.calls",
        "parameters": []
      },
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Iniciar chamada pela sessão Zapo",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipStartCallRequest"
              },
              "example": {
                "session": "5511999999999",
                "peerJid": "5511888888888@s.whatsapp.net",
                "extensionId": "1001"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Chamada iniciada; retorna session e callId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipCall"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Bridge da sessão indisponível."
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Iniciar chamada pela sessão Zapo\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": false,
        "operationId": "postAdminVoipCalls",
        "x-source-route": "/admin/voip/calls",
        "x-source-controller": "voipController.calls",
        "parameters": []
      }
    },
    "/admin/voip/calls/{callId}/{command}": {
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Controlar uma chamada Zapo",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "command",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "accept",
                "reject",
                "end",
                "mute"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session"
                ],
                "properties": {
                  "session": {
                    "type": "string"
                  },
                  "muted": {
                    "type": "boolean",
                    "description": "Obrigatório para o comando mute."
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "session": "5511999999999",
                "muted": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado correlacionado do worker dono da sessão.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Propriedade não comprovada ou sessão divergente; manager_voip_forbidden.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. accept/reject/end/mute exigem uma única chamada ativa da sessão própria. Sessão divergente no corpo é negada. Executar modifica a chamada real.",
        "x-destructive": false,
        "operationId": "postAdminVoipCallsCallIdCommand",
        "x-source-route": "/admin/voip/calls/:callId/:command",
        "x-source-controller": "voipController.command"
      }
    },
    "/admin/voip/recordings/{recordId}": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Reproduzir ou baixar gravação de chamada",
        "description": "Usuário Manager somente com Uno + VoIP compatíveis: upstream capabilities.managerSessionHistoryScope=1. Upstream antigo/incompatível mantém history=false e recordings=false; acesso negado sem fallback global. Credencial e escopo são resolvidos no servidor, não por headers enviados pelo cliente. A atribuição atual governa todo o histórico do phoneNumber salvo no snapshot, inclusive antes da atribuição. Snapshot ausente ou não confiável é excluído para usuário, sem inferir empresa compartilhada ou contato remoto. Remover sessão preserva acesso se a atribuição persistir. Novas requisições consultam a atribuição atual; bytes/blobs já entregues não podem ser revogados. Administrador permanece inalterado. Exige propriedade do recordId exato; nunca substitui por outro registro com o mesmo callId. Valida internamente X-Unoapi-Session-Scope-Applied: 1 antes de transmitir o stream. Header é resposta interna upstream, não parâmetro público. Sem URL global, URL interna ou chave de armazenamento no cliente.",
        "parameters": [
          {
            "name": "recordId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Áudio do registro exato autorizado; sem redirecionamento para URL de armazenamento. A comprovação interna de escopo é validada antes de transmitir bytes.",
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/gsm": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Propriedade/escopo não comprovados; não retorna dados globais ou bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "manager_voip_forbidden"
                }
              }
            }
          },
          "404": {
            "description": "Gravação indisponível ou arquivo não encontrado."
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "operationId": "getAdminVoipRecordingsRecordId",
        "x-source-route": "/admin/voip/recordings/:recordId",
        "x-source-controller": "voipController.recording"
      }
    },
    "/admin/voip/console/calls/{callId}/transfer": {
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Transferir chamada para outro ramal",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetExtensionId"
                ],
                "properties": {
                  "targetExtensionId": {
                    "type": "string",
                    "example": "1002"
                  }
                }
              },
              "example": {
                "targetExtensionId": "1002"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transferência iniciada para o ramal de destino."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "404": {
            "description": "Chamada ou ramal não encontrado."
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Transferir chamada para outro ramal\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": false,
        "operationId": "postAdminVoipConsoleCallsCallIdTransfer"
      }
    },
    "/admin/voip/console/{resource}": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar recursos administrativos de telefonia",
        "parameters": [
          {
            "name": "resource",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/VoipResourcePath"
          }
        ],
        "responses": {
          "200": {
            "description": "Recursos administrativos configurados no serviço de telefonia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Listar recursos administrativos de telefonia\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "getAdminVoipConsoleResource"
      }
    },
    "/admin/voip/console/{resource}/{id}": {
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Criar ou atualizar recurso avançado de telefonia",
        "parameters": [
          {
            "name": "resource",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/VoipResourcePath"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/VoipCompany"
                  },
                  {
                    "$ref": "#/components/schemas/VoipAccount"
                  },
                  {
                    "$ref": "#/components/schemas/VoipLineGroup"
                  },
                  {
                    "$ref": "#/components/schemas/VoipExtensionGroup"
                  },
                  {
                    "$ref": "#/components/schemas/VoipSession"
                  },
                  {
                    "$ref": "#/components/schemas/VoipExtension"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração validada, persistida e devolvida com segredos omitidos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipConfigResponse"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Criar ou atualizar recurso avançado de telefonia\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleResourceId"
      },
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Excluir recurso avançado de telefonia",
        "parameters": [
          {
            "name": "resource",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/VoipResourcePath"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recurso removido e configuração persistida."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Excluir recurso avançado de telefonia\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleResourceId"
      }
    },
    "/admin/voip/console/zapo-lines": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar linhas descobertas pela bridge Zapo",
        "responses": {
          "200": {
            "description": "Inventário de linhas reconciliadas automaticamente com empresa, conta, sessão e ramal SIP/WebRTC.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "lines"
                      ],
                      "properties": {
                        "lines": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/VoipZapoLine"
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "lines": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ManagerVoipLine"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Lista linhas próprias; dados do ramal automático aparecem somente quando o vínculo pode ser comprovado.",
        "operationId": "getAdminVoipConsoleZapoLines",
        "parameters": []
      }
    },
    "/admin/voip/console/zapo-lines/{session}/assign": {
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Alterar a empresa de uma linha Zapo provisionada",
        "description": "O provisionamento inicial é automático. Esta operação permanece disponível somente para uma mudança administrativa posterior de empresa.\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "parameters": [
          {
            "name": "session",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "5566999554300"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "companyId"
                ],
                "properties": {
                  "companyId": {
                    "type": "string",
                    "description": "Empresa de destino já cadastrada."
                  },
                  "companyLabel": {
                    "type": "string",
                    "deprecated": true,
                    "description": "Mantido somente para compatibilidade com clientes antigos."
                  },
                  "label": {
                    "type": "string",
                    "description": "Nome da linha."
                  },
                  "maxConcurrentCalls": {
                    "type": "integer",
                    "minimum": 2,
                    "maximum": 32,
                    "default": 2
                  },
                  "createBasicRoute": {
                    "type": "boolean",
                    "deprecated": true,
                    "description": "Ignorado; o ramal básico é gerenciado automaticamente pela sessão Zapo."
                  }
                }
              },
              "example": {
                "companyId": "empresa-exemplo",
                "label": "Linha de exemplo",
                "maxConcurrentCalls": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mudança idempotente de empresa concluída sem recriar o ramal nem sobrescrever Chatwoot",
            "IA ou roteamento avançado.": null
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "x-destructive": false,
        "operationId": "postAdminVoipConsoleZapoLinesSessionAssign"
      }
    },
    "/admin/voip/console/history": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Consultar histórico de chamadas e gravações",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Alias de pageSize.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página administrativa ou restrita; total contado dentro do escopo antes da paginação.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/VoipHistoryPage"
                    },
                    {
                      "$ref": "#/components/schemas/ManagerVoipHistoryPage"
                    }
                  ]
                },
                "examples": {
                  "usuario": {
                    "summary": "Histórico da sessão atribuída",
                    "value": {
                      "items": [
                        {
                          "id": "registro-exemplo",
                          "callId": "chamada-exemplo",
                          "phoneNumber": "5511999999999",
                          "direction": "inbound",
                          "status": "completed",
                          "recordingStatus": "available"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "pageSize": 20,
                      "totalPages": 1,
                      "scope": {
                        "version": 1,
                        "phones": [
                          "5511999999999"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Propriedade/escopo não comprovados; não retorna dados globais ou bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "manager_voip_forbidden"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "description": "Usuário Manager somente com Uno + VoIP compatíveis: upstream capabilities.managerSessionHistoryScope=1. Upstream antigo/incompatível mantém history=false e recordings=false; acesso negado sem fallback global. Credencial e escopo são resolvidos no servidor, não por headers enviados pelo cliente. A atribuição atual governa todo o histórico do phoneNumber salvo no snapshot, inclusive antes da atribuição. Snapshot ausente ou não confiável é excluído para usuário, sem inferir empresa compartilhada ou contato remoto. Remover sessão preserva acesso se a atribuição persistir. Novas requisições consultam a atribuição atual; bytes/blobs já entregues não podem ser revogados. Administrador permanece inalterado. Filtros e contagem são aplicados antes da paginação pelo snapshot phoneNumber. Valida scope.version=1 e scope.phones exatamente iguais ao conjunto autorizado; qualquer item de outra sessão invalida toda a resposta. Retorna somente campos permitidos, sem URLs globais ou chaves de armazenamento. X-Unoapi-Session-Scope é comunicação interna confiável, não autenticação pública.",
        "operationId": "getAdminVoipConsoleHistory"
      }
    },
    "/admin/voip/console/recording/settings": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Consultar configuração de gravações",
        "responses": {
          "200": {
            "description": "Configuração com segredos omitidos.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recording": {
                      "$ref": "#/components/schemas/VoipRecordingSettings"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Consultar configuração de gravações\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "getAdminVoipConsoleRecordingSettings",
        "parameters": []
      },
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Atualizar configuração de gravações",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipRecordingSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuração de gravação atualizada."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Atualizar configuração de gravações\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleRecordingSettings",
        "parameters": []
      }
    },
    "/admin/voip/console/recording/summary": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Resumir armazenamento de gravações por linha",
        "responses": {
          "200": {
            "description": "Quantidade e bytes armazenados por conta de telefonia.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipRecordingSummary"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Resumir armazenamento de gravações por linha\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "getAdminVoipConsoleRecordingSummary",
        "parameters": []
      }
    },
    "/admin/voip/console/recording/accounts/{accountId}": {
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Limpar gravações armazenadas de uma linha",
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Total de arquivos e bytes removidos.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted",
                    "bytes"
                  ],
                  "properties": {
                    "deleted": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "bytes": {
                      "type": "integer",
                      "format": "int64",
                      "minimum": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Limpar gravações armazenadas de uma linha\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleRecordingAccountsAccountId"
      }
    },
    "/admin/voip/console/extensions/{extensionId}/credentials": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Consultar credenciais SIP e WebRTC do ramal",
        "parameters": [
          {
            "name": "extensionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Credenciais: contrato administrativo ou projeção restrita do ramal automático próprio.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VoipExtensionCredentials"
                    },
                    {
                      "$ref": "#/components/schemas/ManagerVoipCredentials"
                    }
                  ]
                },
                "examples": {
                  "usuario": {
                    "value": {
                      "extensionId": "ramal-auto-exemplo",
                      "username": "1001",
                      "password": "SEGREDO_EXIBIDO_SOMENTE_AO_AUTORIZADO",
                      "sipEndpointMode": "extension",
                      "sipUri": "sip:1001@sip.example.invalid",
                      "sip": {
                        "domain": "sip.example.invalid",
                        "transport": "udp"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "404": {
            "description": "Ramal não encontrado."
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          },
          {
            "ManagerToken": []
          }
        ],
        "description": "Acesso: administrador ou credencial Manager de usuário, limitada aos PNs atribuídos. Papel e propriedade vêm do servidor; empresa em comum não concede acesso. Fluxos legados OAuth/QR/socket permanecem inalterados. Usuário usa o ID exato do ramal automático próprio, validado por PN/linha/sessão; não por empresa. Ramais automáticos próprios em extension ou trunk podem ter suas credenciais consultadas. Trunks externos/compartilhados, ramais manuais, aliases ambíguos e compartilhamento por grupos são negados. Retorna senha SIP desse ramal e coordenadas de conexão, nunca credenciais ICE/TURN compartilhadas. Transferir atribuição impede consultas posteriores pelo antigo proprietário, mas não invalida senha SIP já copiada nem registro ativo. Não há rotação ou desconexão automática; o administrador precisa rotacionar a credencial e desconectar registros pelo processo de telefonia suportado para revogação externa completa.",
        "operationId": "getAdminVoipConsoleExtensionsExtensionIdCredentials"
      }
    },
    "/admin/voip/console/extensions/{extensionId}/registrations/{registrationId}": {
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Desconectar registro ativo de um ramal",
        "parameters": [
          {
            "name": "extensionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "registrationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "webrtc",
                "sip_rtp"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Registro desconectado e lista ativa atualizada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dropped": {
                      "type": "boolean"
                    },
                    "registrationId": {
                      "type": "string"
                    },
                    "registrations": {
                      "$ref": "#/components/schemas/VoipRegistrations"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "404": {
            "description": "Ramal ou registro não encontrado."
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Desconectar registro ativo de um ramal\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente. Usuário Manager comum: sempre negado (disconnectRegistration=false), pois o upstream resolve aliases globais e pode fechar sockets compartilhados. Exclusivo do processo administrativo de telefonia.",
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleExtensionsExtensionIdRegistrationsRegistrationId"
      }
    },
    "/admin/voip/console/extensionGroups/{extensionGroupId}/transfer-audio": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Reproduzir áudio de transferência do grupo",
        "parameters": [
          {
            "name": "extensionGroupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Arquivo de áudio configurado.",
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Reproduzir áudio de transferência do grupo\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "getAdminVoipConsoleExtensionGroupsExtensionGroupIdTransferAudio"
      },
      "put": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Substituir áudio de transferência do grupo",
        "parameters": [
          {
            "name": "extensionGroupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-File-Name",
            "in": "header",
            "required": false,
            "description": "Nome original codificado com encodeURIComponent.",
            "schema": {
              "type": "string",
              "example": "transferencia.mp3"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "audio/mpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "audio/wav": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Áudio validado e persistido."
          },
          "400": {
            "description": "Arquivo vazio."
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "413": {
            "description": "Arquivo acima do limite padrão de 15 MB."
          },
          "415": {
            "description": "Tipo diferente de MP3 ou WAV."
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Substituir áudio de transferência do grupo\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": false,
        "operationId": "putAdminVoipConsoleExtensionGroupsExtensionGroupIdTransferAudio"
      }
    },
    "/admin/voip/console/router/resolve-inbound": {
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Simular roteamento de entrada",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipResolveInboundRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da simulação, sem abrir chamada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipRouterResult"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Simular roteamento de entrada\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "postAdminVoipConsoleRouterResolveInbound",
        "parameters": []
      }
    },
    "/admin/voip/console/router/resolve-outbound": {
      "post": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Simular roteamento de saída",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoipResolveOutboundRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da simulação, sem abrir chamada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoipRouterResult"
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Simular roteamento de saída\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "postAdminVoipConsoleRouterResolveOutbound",
        "parameters": []
      }
    },
    "/admin/voip/console/router/locks": {
      "get": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Listar reservas ativas do roteador",
        "responses": {
          "200": {
            "description": "Reservas atuais, isoladas por chamada e linha Zapo.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "locks"
                  ],
                  "properties": {
                    "locks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipRouterLock"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Listar reservas ativas do roteador\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo.",
        "operationId": "getAdminVoipConsoleRouterLocks",
        "parameters": []
      }
    },
    "/admin/voip/console/router/locks/{lockId}": {
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Liberar uma reserva do roteador",
        "parameters": [
          {
            "name": "lockId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado da liberação e reservas restantes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "released": {
                      "type": "boolean"
                    },
                    "locks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipRouterLock"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Liberar uma reserva do roteador\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleRouterLocksLockId"
      }
    },
    "/admin/voip/console/router/calls/{callId}/locks": {
      "delete": {
        "tags": [
          "Telefonia"
        ],
        "summary": "Liberar todas as reservas de uma chamada",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quantidade liberada e reservas restantes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "released": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "locks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VoipRouterLock"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_credentials"
                }
              }
            }
          },
          "403": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "admin_token_required"
                }
              }
            }
          },
          "502": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_unavailable"
                }
              }
            }
          },
          "503": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_not_configured"
                }
              }
            }
          },
          "504": {
            "description": "Erro da operação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "voip_service_timeout"
                }
              }
            }
          }
        },
        "security": [
          {
            "AdminToken": []
          }
        ],
        "description": "Liberar todas as reservas de uma chamada\n\nAcesso: administrador autenticado (token global da stack ou login Manager com papel admin). Usuários comuns não recebem acesso global. Fluxos legados OAuth/QR/socket permanecem inalterados; não é garantia de isolamento multitenant completo. Atenção: executar altera o estado real. Revise IDs, corpo e impacto antes de enviar; não execute coleções inteiras automaticamente.",
        "x-destructive": true,
        "operationId": "deleteAdminVoipConsoleRouterCallsCallIdLocks"
      }
    },
    "/webhooks/whatsapp": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Receber evento encaminhado pelo webhook",
        "description": "Operação exposta pelo controller `webhookController.whatsappNoParam` na versão atual.",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postWebhooksWhatsapp",
        "x-source-route": "/webhooks/whatsapp",
        "x-source-controller": "webhookController.whatsappNoParam"
      },
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Validar assinatura do webhook",
        "description": "Operação exposta pelo controller `webhookController.whatsappVerifyNoParam` na versão atual.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getWebhooksWhatsapp",
        "x-source-route": "/webhooks/whatsapp",
        "x-source-controller": "webhookController.whatsappVerifyNoParam"
      }
    },
    "/connect/{phone}": {
      "get": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Conectar sessão e acompanhar o QR code",
        "description": "Operação exposta pelo controller `connectController.index` na versão atual.",
        "parameters": [
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getConnectPhone",
        "x-source-route": "/connect/:phone",
        "x-source-controller": "connectController.index"
      }
    },
    "/passkey-bridge/pending": {
      "get": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Consultar pareamento pendente mais recente",
        "description": "Operação exposta pelo controller `passkeyBridgeController.pendingLatest` na versão atual.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getPasskeyBridgePending",
        "x-source-route": "/passkey-bridge/pending",
        "x-source-controller": "passkeyBridgeController.pendingLatest"
      }
    },
    "/passkey-bridge/{bridgeId}/pending": {
      "get": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Consultar desafio de pareamento",
        "description": "Operação exposta pelo controller `passkeyBridgeController.pending` na versão atual.",
        "parameters": [
          {
            "name": "bridgeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getPasskeyBridgeBridgeIdPending",
        "x-source-route": "/passkey-bridge/:bridgeId/pending",
        "x-source-controller": "passkeyBridgeController.pending"
      }
    },
    "/passkey-bridge/{bridgeId}/status": {
      "get": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Consultar estado do pareamento",
        "description": "Operação exposta pelo controller `passkeyBridgeController.status` na versão atual.",
        "parameters": [
          {
            "name": "bridgeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getPasskeyBridgeBridgeIdStatus",
        "x-source-route": "/passkey-bridge/:bridgeId/status",
        "x-source-controller": "passkeyBridgeController.status"
      }
    },
    "/passkey-bridge/{bridgeId}/assertion": {
      "post": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Enviar resposta do desafio de pareamento",
        "description": "Operação exposta pelo controller `passkeyBridgeController.assertion` na versão atual.",
        "parameters": [
          {
            "name": "bridgeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postPasskeyBridgeBridgeIdAssertion",
        "x-source-route": "/passkey-bridge/:bridgeId/assertion",
        "x-source-controller": "passkeyBridgeController.assertion"
      }
    },
    "/passkey-bridge/{bridgeId}/confirm": {
      "post": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Confirmar pareamento",
        "description": "Operação exposta pelo controller `passkeyBridgeController.confirm` na versão atual.",
        "parameters": [
          {
            "name": "bridgeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postPasskeyBridgeBridgeIdConfirm",
        "x-source-route": "/passkey-bridge/:bridgeId/confirm",
        "x-source-controller": "passkeyBridgeController.confirm"
      }
    },
    "/passkey-bridge/{bridgeId}": {
      "delete": {
        "tags": [
          "Pareamento"
        ],
        "summary": "Cancelar pareamento",
        "description": "Operação exposta pelo controller `passkeyBridgeController.cancel` na versão atual.",
        "parameters": [
          {
            "name": "bridgeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "deletePasskeyBridgeBridgeId",
        "x-source-route": "/passkey-bridge/:bridgeId",
        "x-source-controller": "passkeyBridgeController.cancel"
      }
    },
    "/{version}/{media_id}": {
      "get": {
        "tags": [
          "Mídia"
        ],
        "summary": "Consultar mídia pelo identificador",
        "description": "Operação exposta pelo controller `mediaController.typebot` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "media_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getVersionMediaId",
        "x-source-route": "/:version/:media_id(\\\\d+-[A-Za-z0-9_-]+)",
        "x-source-controller": "mediaController.indexNoPhone"
      }
    },
    "/{version}/{phone}/webhooks/{webhook_id}": {
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Atualizar configuração de um webhook",
        "description": "Operação exposta pelo controller `registrationController.updateWebhook` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "patchVersionPhoneWebhooksWebhookId",
        "x-source-route": "/:version/:phone/webhooks/:webhook_id",
        "x-source-controller": "registrationController.updateWebhook"
      }
    },
    "/{version}/{phone}/debug/app_state_resync": {
      "post": {
        "tags": [
          "Diagnóstico"
        ],
        "summary": "Ressincronizar estado da sessão",
        "description": "Operação exposta pelo controller `phoneNumberController.resyncAppState` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneDebugAppStateResync",
        "x-source-route": "/:version/:phone/debug/app_state_resync",
        "x-source-controller": "phoneNumberController.resyncAppState"
      }
    },
    "/{version}/{phone}/debug/history_on_demand": {
      "post": {
        "tags": [
          "Diagnóstico"
        ],
        "summary": "Solicitar sincronização de histórico",
        "description": "Operação exposta pelo controller `phoneNumberController.historyOnDemand` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneDebugHistoryOnDemand",
        "x-source-route": "/:version/:phone/debug/history_on_demand",
        "x-source-controller": "phoneNumberController.historyOnDemand"
      }
    },
    "/{version}/{phone}/templates/{templateId}": {
      "delete": {
        "tags": [
          "Modelos de mensagem"
        ],
        "summary": "Excluir modelo de mensagem",
        "description": "Operação exposta pelo controller `templatesController.destroy` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "templateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "deleteVersionPhoneTemplatesTemplateId",
        "x-source-route": "/:version/:phone/templates/:templateId",
        "x-source-controller": "templatesController.destroy"
      }
    },
    "/{version}/{phone}/messages/{messageId}/recover_delivery": {
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Recuperar entrega de uma mensagem",
        "description": "Operação exposta pelo controller `messagesController.recoverDelivery` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneMessagesMessageIdRecoverDelivery",
        "x-source-route": "/:version/:phone/messages/:messageId/recover_delivery",
        "x-source-controller": "messagesController.recoverDelivery"
      }
    },
    "/{version}/{phone}/messages/recover_delivery": {
      "post": {
        "tags": [
          "Mensagens"
        ],
        "summary": "Recuperar entregas pendentes",
        "description": "Operação exposta pelo controller `messagesController.recoverDelivery` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneMessagesRecoverDelivery",
        "x-source-route": "/:version/:phone/messages/recover_delivery",
        "x-source-controller": "messagesController.recoverDelivery"
      }
    },
    "/{version}/{phone}/groups/{groupId}/invite-link": {
      "get": {
        "tags": [
          "Grupos"
        ],
        "summary": "Consultar link de convite do grupo",
        "description": "Operação exposta pelo controller `groupsController.inviteLink` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getVersionPhoneGroupsGroupIdInviteLink",
        "x-source-route": "/:version/:phone/groups/:groupId/invite-link",
        "x-source-controller": "groupsController.inviteLink"
      },
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Gerar novo link de convite do grupo",
        "description": "Operação exposta pelo controller `groupsController.resetInviteLink` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneGroupsGroupIdInviteLink",
        "x-source-route": "/:version/:phone/groups/:groupId/invite-link",
        "x-source-controller": "groupsController.resetInviteLink"
      }
    },
    "/{version}/{phone}/groups/{groupId}/join_requests": {
      "get": {
        "tags": [
          "Grupos"
        ],
        "summary": "Listar solicitações de entrada no grupo",
        "description": "Operação exposta pelo controller `groupsController.joinRequests` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "getVersionPhoneGroupsGroupIdJoinRequests",
        "x-source-route": "/:version/:phone/groups/:groupId/join_requests",
        "x-source-controller": "groupsController.joinRequests"
      },
      "post": {
        "tags": [
          "Grupos"
        ],
        "summary": "Aprovar solicitações de entrada no grupo",
        "description": "Operação exposta pelo controller `groupsController.approveJoinRequests` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "postVersionPhoneGroupsGroupIdJoinRequests",
        "x-source-route": "/:version/:phone/groups/:groupId/join_requests",
        "x-source-controller": "groupsController.approveJoinRequests"
      },
      "delete": {
        "tags": [
          "Grupos"
        ],
        "summary": "Rejeitar solicitações de entrada no grupo",
        "description": "Operação exposta pelo controller `groupsController.rejectJoinRequests` na versão atual.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operação processada."
          }
        },
        "security": [
          {
            "ApiToken": []
          }
        ],
        "operationId": "deleteVersionPhoneGroupsGroupIdJoinRequests",
        "x-source-route": "/:version/:phone/groups/:groupId/join_requests",
        "x-source-controller": "groupsController.rejectJoinRequests"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AdminToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token global da stack ou login Manager com papel admin resolvido no servidor. Chaves pessoais de usuários comuns não autorizam infraestrutura global. Exemplos não executam ações automaticamente."
      },
      "ManagerLoginToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token de login do Manager (12 horas). Chaves de API não podem listar, criar ou revogar chaves pessoais nem alterar senha. Administrador usa o token global, sem senha ou chave pessoal nessas rotas."
      },
      "ManagerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Credencial do Manager. Login de 12 horas; chaves pessoais separadas da senha, padrão 90 dias e máximo 365. Papel derivado do token. Isolamento limitado, não segurança multitenant completa: OAuth legado, QR público e socket explicitamente inalterados a pedido do usuário. Infraestrutura global exclusiva do administrador. Usuários não alteram authToken/storage/proxyUrl/baseStore nem visualizam credenciais globais. A exceção é a credencial SIP do ramal automático próprio não compartilhado, com vínculo comprovado. Mídia exige sessão explícita. VoIP permite inventário próprio, modo SIP restrito e accept/reject/end/mute. Histórico/gravações por snapshot PN exigem Uno e VoIP compatíveis com managerSessionHistoryScope=1; upstream antigo nega acesso. Configuração global, originate e desconexão de registros permanecem negados. Transferir atribuição não invalida senha SIP copiada, registros ativos ou bytes de áudio já entregues. Recurso local, não implantado."
      },
      "ApiToken": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "API token. Ex.: 1 ou Bearer <token>"
      }
    },
    "parameters": {
      "PhonePath": {
        "name": "phone",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Número (ID) da sessão, ex.: 5511999999999"
      },
      "GroupIdPath": {
        "name": "groupId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "JID do grupo, ex.: 120363040468224422@g.us"
      },
      "VoipResourcePath": {
        "name": "resource",
        "in": "path",
        "required": true,
        "description": "Coleção administrativa da telefonia.",
        "schema": {
          "type": "string",
          "enum": [
            "companies",
            "accounts",
            "lineGroups",
            "extensionGroups",
            "sessions",
            "extensions"
          ]
        }
      }
    },
    "schemas": {
      "SessionConversation": {
        "type": "object",
        "required": [
          "id",
          "name",
          "kind",
          "timestamp_ms",
          "last_message_id",
          "preview",
          "type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "123456789@lid"
          },
          "name": {
            "type": "string"
          },
          "phone_number": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "direct",
              "group"
            ]
          },
          "timestamp_ms": {
            "type": "integer",
            "format": "int64"
          },
          "last_message_id": {
            "type": "string"
          },
          "preview": {
            "type": "string",
            "maxLength": 180
          },
          "picture_id": {
            "type": "string",
            "description": "Identidade para o endpoint autenticado de profile-pictures; ícone quando foto ausente"
          },
          "type": {
            "type": "string"
          }
        }
      },
      "SessionConversationMessage": {
        "type": "object",
        "required": [
          "id",
          "conversation_id",
          "from_me",
          "timestamp_ms",
          "type",
          "text"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID de provider para paginação/deltas/mídia"
          },
          "reply_id": {
            "type": "string",
            "description": "ID UnoAPI mapeado ou ID de provider para responder"
          },
          "conversation_id": {
            "type": "string"
          },
          "from_me": {
            "type": "boolean"
          },
          "sender": {
            "type": "string"
          },
          "sender_name": {
            "type": "string",
            "maxLength": 200,
            "description": "Nome do participante do grupo resolvido no cache da própria sessão; sender preserva a identidade original"
          },
          "timestamp_ms": {
            "type": "integer",
            "format": "int64"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "audio",
              "document",
              "sticker",
              "contact",
              "location",
              "interactive",
              "view_once",
              "revoked",
              "unsupported"
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 16000
          },
          "reply_to": {
            "type": "string"
          },
          "reply_preview": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "text": {
                "type": "string",
                "maxLength": 180
              },
              "type": {
                "type": "string"
              },
              "sender": {
                "type": "string"
              },
              "sender_name": {
                "type": "string",
                "maxLength": 200,
                "description": "Nome do autor da mensagem citada no cache da sessão"
              },
              "available": {
                "type": "boolean",
                "description": "Original encontrado no histórico local; false pode ter prévia embutida na citação"
              }
            }
          },
          "edited": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "contacts": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "maxLength": 200
                },
                "phones": {
                  "type": "array",
                  "maxItems": 5,
                  "items": {
                    "type": "string",
                    "maxLength": 20
                  }
                }
              }
            }
          },
          "buttons": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 100
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "maxLength": 2048,
                  "description": "Somente links HTTP(S) sem credenciais"
                }
              }
            }
          },
          "media": {
            "type": "object",
            "nullable": true,
            "properties": {
              "mime_type": {
                "type": "string"
              },
              "filename": {
                "type": "string"
              },
              "available": {
                "type": "boolean",
                "description": "Referência de mídia; não garante disponibilidade no CDN"
              }
            }
          },
          "location": {
            "type": "object",
            "properties": {
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              }
            }
          }
        }
      },
      "PrivacyInput": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "mode",
              "userJids"
            ],
            "description": "Substitui público dos próximos Status. CONTACTS exige lista vazia; ALLOW_LIST/DENY_LIST exigem de 1 a 100 contatos. Números viram JIDs PN, LIDs são preservados e duplicados removidos. Não consulta público atual, não publica Status nem envia flags Facebook/Instagram.",
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "status"
                ]
              },
              "mode": {
                "type": "string",
                "enum": [
                  "CONTACTS",
                  "DENY_LIST",
                  "ALLOW_LIST"
                ]
              },
              "userJids": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/PrivacyContactId"
                }
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "setting",
              "value"
            ],
            "description": "Valores: lastSeen/profilePicture/about/linkedProfiles/pix = all|contacts|contact_blacklist|none; online = all|none|match_last_seen; readReceipts = all|none; groupAdd = all|contacts|contact_blacklist; callAdd = all|known|contacts; messages = all|contacts; defenseMode = off|on_standard. Valor incompatível com setting é rejeitado.",
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "setting"
                ]
              },
              "setting": {
                "type": "string",
                "enum": [
                  "lastSeen",
                  "online",
                  "profilePicture",
                  "about",
                  "readReceipts",
                  "groupAdd",
                  "callAdd",
                  "messages",
                  "defenseMode",
                  "linkedProfiles",
                  "pix"
                ]
              },
              "value": {
                "type": "string",
                "enum": [
                  "all",
                  "contacts",
                  "contact_blacklist",
                  "none",
                  "match_last_seen",
                  "known",
                  "off",
                  "on_standard"
                ]
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "setting"
            ],
            "description": "Pelo menos um ID em add ou remove; mesmo ID não pode estar nas duas listas. Não substitui toda a lista.",
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "exceptions"
                ]
              },
              "setting": {
                "type": "string",
                "enum": [
                  "about",
                  "groupAdd",
                  "lastSeen",
                  "profilePicture",
                  "linkedProfiles",
                  "pix"
                ]
              },
              "add": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/PrivacyContactId"
                }
              },
              "remove": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/PrivacyContactId"
                }
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "jid"
            ],
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "block",
                  "unblock"
                ]
              },
              "jid": {
                "$ref": "#/components/schemas/PrivacyContactId"
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "operation",
              "duration"
            ],
            "properties": {
              "operation": {
                "type": "string",
                "enum": [
                  "timer"
                ]
              },
              "duration": {
                "type": "integer",
                "enum": [
                  0,
                  86400,
                  604800,
                  7776000
                ]
              }
            }
          }
        ]
      },
      "PrivacyContactId": {
        "type": "string",
        "pattern": "^\\d{5,20}(?:@(?:s\\.whatsapp\\.net|lid))?$",
        "description": "Número com país e DDD somente dígitos ou JID PN/LID. Não aceita grupos nem username nesta rota."
      },
      "AccountEmailStatus": {
        "type": "object",
        "required": [
          "email",
          "verified",
          "confirmed"
        ],
        "properties": {
          "email": {
            "type": "string",
            "nullable": true,
            "format": "email"
          },
          "verified": {
            "type": "boolean"
          },
          "confirmed": {
            "type": "boolean"
          }
        }
      },
      "OwnProfileMutation": {
        "type": "object",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "id": {
            "type": "string",
            "nullable": true,
            "description": "ID de foto ou capa retornado pelo SDK"
          },
          "warning": {
            "type": "string",
            "description": "Alteração remota confirmada mas persistência ou limpeza local incompleta"
          }
        }
      },
      "OwnProfile": {
        "type": "object",
        "properties": {
          "mobile_primary": {
            "type": "boolean",
            "description": "Habilita o fluxo de e-mail da conta",
            "separado do e-mail comercial": null
          },
          "cover": {
            "type": "object",
            "nullable": true,
            "description": "Última capa enviada pela Uno; não representa consulta da capa remota. Registro independente do cache de perfil.",
            "properties": {
              "id": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "URL S3 assinada por 900 segundos",
                "renovada em cada GET": null
              },
              "source": {
                "type": "string",
                "enum": [
                  "uno_upload"
                ]
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "cache": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "enum": [
                  "cache",
                  "live"
                ]
              },
              "updated_at": {
                "type": "string",
                "format": "date-time",
                "description": "Momento da última consulta armazenada",
                "que pode ser parcial conforme warnings": null
              },
              "stale": {
                "type": "boolean"
              },
              "refresh_failed": {
                "type": "boolean"
              }
            }
          },
          "name": {
            "type": "string"
          },
          "about": {
            "type": "string",
            "nullable": true
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "verified_name": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "business_account": {
            "type": "boolean",
            "nullable": true
          },
          "picture": {
            "type": "object",
            "nullable": true,
            "properties": {
              "url": {
                "type": "string"
              },
              "id": {
                "type": "string"
              }
            }
          },
          "business": {
            "type": "object",
            "nullable": true,
            "description": "Perfil comercial lido da Zapo; campos de OwnBusinessInput, jid, categorias com id/name e profileOptions.",
            "additionalProperties": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Seções cuja consulta falhou; não confundir com dados apagados"
          },
          "unsupported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "OwnBusinessInput": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": false,
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 1024
          },
          "address": {
            "type": "string",
            "maxLength": 1024
          },
          "email": {
            "type": "string",
            "maxLength": 254,
            "description": "E-mail válido ou string vazia para limpar"
          },
          "latitude": {
            "type": "number",
            "minimum": -90,
            "maximum": 90,
            "description": "Enviar junto com longitude; zero permitido"
          },
          "longitude": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          "websites": {
            "type": "array",
            "maxItems": 2,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "maxLength": 2048,
                  "description": "URL HTTP ou HTTPS"
                }
              }
            }
          },
          "categories": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^[0-9]+$",
                  "maxLength": 64
                }
              }
            }
          },
          "businessHours": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "config"
            ],
            "properties": {
              "timezone": {
                "type": "string",
                "maxLength": 100,
                "example": "America/Cuiaba"
              },
              "config": {
                "type": "array",
                "maxItems": 7,
                "description": "Uma entrada por dia aberto. Dias fechados omitidos; specific_hours requer início menor que fim. Limite local de um intervalo por dia.",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "dayOfWeek",
                    "mode"
                  ],
                  "properties": {
                    "dayOfWeek": {
                      "type": "string",
                      "enum": [
                        "sun",
                        "mon",
                        "tue",
                        "wed",
                        "thu",
                        "fri",
                        "sat"
                      ]
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "open_24h",
                        "specific_hours",
                        "appointment_only"
                      ]
                    },
                    "openTime": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1439,
                      "description": "Minutos desde meia-noite; somente specific_hours"
                    },
                    "closeTime": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1439
                    }
                  }
                }
              }
            }
          }
        }
      },
      "MobileRegistrationStatus": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "idle",
              "requesting",
              "code_required",
              "verifying",
              "registered",
              "blocked",
              "uncertain",
              "additional_confirmation_required"
            ]
          },
          "canonicalPhone": {
            "type": "string",
            "description": "Número devolvido pelo servidor após registro confirmado"
          },
          "error": {
            "type": "string",
            "description": "Categoria sanitizada sem resposta bruta ou credenciais"
          },
          "retryAt": {
            "type": "integer",
            "format": "int64",
            "description": "Fim da espera remota em Unix milissegundos, calculado com diagnostic.smsWaitSeconds ou espera conservadora. Ausente quando o prazo remoto é desconhecido. Não garante liberação nem inicia reenvio."
          },
          "retryAtVoice": {
            "type": "integer",
            "format": "int64",
            "description": "Fim da espera para ligação em Unix milissegundos; não solicita chamada automaticamente"
          },
          "method": {
            "type": "string",
            "enum": [
              "sms",
              "voice"
            ],
            "description": "Método da última solicitação"
          },
          "canRetryVerification": {
            "type": "boolean",
            "description": "Permite confirmação manual com confirmRecovery; nunca reenvia SMS"
          },
          "canResendSms": {
            "type": "boolean",
            "description": "Permite reenvio manual com confirmResend, preservando as chaves. Em code_required, respeita eventual espera remota do envio aceito; sem prazo, permite tentativa explícita. Falha legada ou código expirado: cinco minutos e um reenvio; device_confirm_or_second_code: após prazo remoto conhecido, sem outra pendência e sem teto local; too_recent na solicitação sem desafio: somente após prazo remoto conhecido, sem teto local de solicitações. Nunca representa garantia de liberação pelo provedor."
          },
          "canResendVoice": {
            "type": "boolean",
            "description": "Permite nova solicitação explícita por ligação com confirmResend; respeita voice_wait e preserva as chaves"
          },
          "diagnostic": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "stage": {
                "type": "string",
                "enum": [
                  "prepare",
                  "request",
                  "verify",
                  "check"
                ]
              },
              "reason": {
                "type": "string",
                "description": "Motivo técnico de lista permitida; nunca texto bruto do provedor"
              },
              "httpStatus": {
                "type": "integer",
                "minimum": 100,
                "maximum": 599
              },
              "providerStatus": {
                "type": "string",
                "pattern": "^[a-z][a-z_]{1,47}$",
                "description": "Código de status retornado pelo componente"
              },
              "providerReason": {
                "type": "string",
                "pattern": "^[a-z][a-z_]{1,47}$",
                "description": "Código técnico do motivo; não inclui texto livre"
              },
              "providerPending": {
                "type": "string",
                "pattern": "^[a-z][a-z_]{1,47}$",
                "description": "Código técnico de pendência; não comprova aprovação no aparelho"
              },
              "waitSeconds": {
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483647,
                "description": "Espera remota em segundos: espera do método solicitado, maior espera dos demais métodos ou retry_after. Tem prioridade sobre a espera local."
              },
              "smsWaitSeconds": {
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483647
              },
              "voiceWaitSeconds": {
                "type": "integer",
                "minimum": 0,
                "maximum": 2147483647
              }
            }
          }
        }
      },
      "MobileDeviceDraft": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "phone",
          "name",
          "platform",
          "accountType",
          "connectionMode",
          "state",
          "createdAt",
          "createdBy"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "phone": {
            "type": "string",
            "pattern": "^[1-9][0-9]{7,14}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "platform": {
            "type": "string",
            "enum": [
              "android",
              "ios"
            ]
          },
          "accountType": {
            "type": "string",
            "enum": [
              "personal",
              "business"
            ]
          },
          "connectionMode": {
            "type": "string",
            "enum": [
              "mobile_primary"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "draft",
              "deleting"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          }
        }
      },
      "ManagerVoipHistoryScope": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "phones"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "phones": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ManagerVoipHistoryItem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "phoneNumber"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "callId": {
            "type": "string"
          },
          "phoneNumber": {
            "type": "string",
            "description": "PN confiável da sessão salvo no snapshot histórico."
          },
          "direction": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "accountLabel": {
            "type": "string"
          },
          "extensionId": {
            "type": "string"
          },
          "extensionUsername": {
            "type": "string"
          },
          "extensionLabel": {
            "type": "string"
          },
          "remoteNumber": {
            "type": "string"
          },
          "remoteName": {
            "type": "string"
          },
          "remoteNameSource": {
            "type": "string"
          },
          "remoteJid": {
            "type": "string"
          },
          "startedAt": {
            "type": "string"
          },
          "answeredAt": {
            "type": "string"
          },
          "endedAt": {
            "type": "string"
          },
          "endReason": {
            "type": "string"
          },
          "recordingStatus": {
            "type": "string"
          },
          "recordingMime": {
            "type": "string"
          },
          "aiSummaryStatus": {
            "type": "string"
          },
          "aiTranscriptText": {
            "type": "string"
          },
          "aiSummaryText": {
            "type": "string"
          },
          "durationSeconds": {
            "type": "number"
          },
          "recordingSizeBytes": {
            "type": "number"
          },
          "recordingDurationSeconds": {
            "type": "number"
          }
        }
      },
      "ManagerVoipHistoryPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "items",
          "total",
          "page",
          "pageSize",
          "totalPages",
          "scope"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManagerVoipHistoryItem"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "totalPages": {
            "type": "integer",
            "minimum": 1
          },
          "scope": {
            "$ref": "#/components/schemas/ManagerVoipHistoryScope"
          },
          "search": {
            "type": "string"
          },
          "startDate": {
            "type": "string"
          },
          "endDate": {
            "type": "string"
          }
        }
      },
      "ManagerVoipCapabilities": {
        "type": "object",
        "properties": {
          "scoped": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "activeCalls": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "callCommands": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "createCalls": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "history": {
            "type": "boolean",
            "default": false,
            "description": "true somente com upstream capabilities.managerSessionHistoryScope=1 e Uno compatível. Upstream antigo mantém false e nega acesso."
          },
          "recordings": {
            "type": "boolean",
            "default": false,
            "description": "true somente com upstream capabilities.managerSessionHistoryScope=1 e Uno compatível. Upstream antigo mantém false e nega acesso."
          },
          "configuration": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "lines": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "automaticExtensions": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "extensionCredentials": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "extensionSipMode": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "disconnectRegistration": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "basicInboundSettings": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "ManagerVoipExtension": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "sipEndpointMode": {
            "type": "string",
            "enum": [
              "extension",
              "trunk"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "hasPassword": {
            "type": "boolean"
          }
        }
      },
      "ManagerVoipLine": {
        "type": "object",
        "properties": {
          "session": {
            "type": "string"
          },
          "connected": {
            "type": "boolean"
          },
          "connectedAt": {
            "type": "string"
          },
          "lastSeenAt": {
            "type": "string"
          },
          "maxConcurrentCalls": {
            "type": "number"
          },
          "sessionId": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "assignmentStatus": {
            "type": "string"
          },
          "configuredMaxConcurrentCalls": {
            "type": "number"
          },
          "routingConfigured": {
            "type": "boolean"
          },
          "automatic": {
            "type": "object",
            "properties": {
              "extensionId": {
                "type": "string"
              },
              "username": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "basicInboundEnabled": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "ManagerVoipCredentials": {
        "type": "object",
        "properties": {
          "extensionId": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "password": {
            "type": "string",
            "format": "password"
          },
          "type": {
            "type": "string"
          },
          "sipEndpointMode": {
            "type": "string",
            "enum": [
              "extension",
              "trunk"
            ]
          },
          "sipUri": {
            "type": "string"
          },
          "sip": {
            "type": "object",
            "properties": {
              "domain": {
                "type": "string"
              },
              "lanDomain": {
                "type": "string"
              },
              "wsPath": {
                "type": "string"
              },
              "publicWsUrl": {
                "type": "string"
              },
              "lanWsUrl": {
                "type": "string"
              },
              "transport": {
                "type": "string"
              }
            }
          }
        }
      },
      "ManagerVoipBootstrap": {
        "type": "object",
        "properties": {
          "capabilities": {
            "$ref": "#/components/schemas/ManagerVoipCapabilities"
          },
          "accounts": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "sessions": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "extensions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManagerVoipExtension"
            }
          },
          "zapoLines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManagerVoipLine"
            }
          },
          "bridges": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipCall"
            }
          }
        }
      },
      "ManagerUser": {
        "type": "object",
        "required": [
          "id",
          "username",
          "name",
          "role",
          "active"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "user"
            ]
          },
          "active": {
            "type": "boolean"
          }
        }
      },
      "ManagerKey": {
        "type": "object",
        "required": [
          "id",
          "userId",
          "name",
          "createdAt",
          "expiresAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ManagerAssignmentEvent": {
        "type": "object",
        "required": [
          "phone",
          "from",
          "to",
          "at",
          "actor"
        ],
        "properties": {
          "phone": {
            "type": "string"
          },
          "from": {
            "type": "string",
            "nullable": true
          },
          "to": {
            "type": "string",
            "nullable": true
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "actor": {
            "type": "string"
          }
        }
      },
      "WebhookHistorySnapshot": {
        "type": "object",
        "required": [
          "id",
          "archived_at",
          "reason",
          "server",
          "webhooks"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "archived_at": {
            "type": "string",
            "format": "date-time"
          },
          "reason": {
            "type": "string",
            "enum": [
              "updated",
              "removed",
              "restored"
            ]
          },
          "server": {
            "type": "string"
          },
          "webhooks": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "destination",
                "has_credentials",
                "events"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "destination": {
                  "type": "string",
                  "description": "Somente origem da URL, sem credenciais, caminho ou parâmetros."
                },
                "has_credentials": {
                  "type": "boolean"
                },
                "events": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Flags send* que estavam habilitadas."
                }
              }
            }
          }
        }
      },
      "SessionWebhookDestinationInput": {
        "type": "object",
        "required": [
          "name",
          "url",
          "server",
          "enabled",
          "session_ids",
          "auto_include_new_sessions",
          "events"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "HTTP(S), sem usuário/senha ou fragmento. HTTPS recomendado. Redirecionamentos não são seguidos."
          },
          "server": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "example": "server_1"
          },
          "enabled": {
            "type": "boolean"
          },
          "session_ids": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "type": "string",
              "pattern": "^\\d{5,20}$"
            }
          },
          "auto_include_new_sessions": {
            "type": "boolean",
            "description": "Apenas novas sessões Zapo desse servidor; não seleciona sessões atuais."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SessionLifecycleEventName"
            }
          },
          "heartbeat_interval_seconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 86400,
            "default": 300
          },
          "bearer_token": {
            "type": "string",
            "maxLength": 4096,
            "writeOnly": true,
            "description": "Opcional. Omitido preserva ao editar; vazio remove."
          },
          "signing_secret": {
            "type": "string",
            "maxLength": 4096,
            "pattern": "^(?:[^\\r\\n]{32,4096})?$",
            "writeOnly": true,
            "description": "Opcional. Omitido na criação ou vazio desativa HMAC. Omitido ao editar preserva; vazio remove. Não vazio exige mínimo 32 caracteres. Nunca devolvido."
          }
        }
      },
      "SessionWebhookDestination": {
        "type": "object",
        "required": [
          "id",
          "name",
          "url",
          "server",
          "enabled",
          "session_ids",
          "auto_include_new_sessions",
          "events",
          "heartbeat_interval_seconds",
          "revision",
          "has_bearer_token",
          "has_signing_secret"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "server": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "session_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "auto_include_new_sessions": {
            "type": "boolean"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionLifecycleEventName"
            }
          },
          "heartbeat_interval_seconds": {
            "type": "integer"
          },
          "revision": {
            "type": "string",
            "format": "uuid"
          },
          "has_bearer_token": {
            "type": "boolean"
          },
          "has_signing_secret": {
            "type": "boolean"
          }
        }
      },
      "SessionLifecycleEventName": {
        "type": "string",
        "enum": [
          "session.connected",
          "session.disconnected",
          "session.unlinked",
          "session.removed",
          "session.unavailable",
          "session.heartbeat"
        ]
      },
      "SessionLifecycleState": {
        "type": "string",
        "enum": [
          "connected",
          "disconnected",
          "unlinked",
          "removed",
          "unavailable"
        ]
      },
      "SessionLifecycleEvent": {
        "type": "object",
        "description": "POST independente do envelope compatível. Entregas podem se repetir ou chegar fora de ordem:\ndeduplicar por destination_id + event_id e aplicar somente state.sequence superior.\nHMAC SHA-256 de timestamp Unix em segundos + ponto + bytes exatos do corpo UTF-8,\nusando signing_secret somente quando configurado. Headers X-ViperConnect-Timestamp e\nX-ViperConnect-Event-Id sempre enviados; X-ViperConnect-Signature (sha256=hex) apenas com HMAC.\nQuando configurado, verifique assinatura em tempo constante e janela de 5 minutos.\n",
        "required": [
          "schema_version",
          "event_id",
          "event",
          "occurred_at",
          "destination_id",
          "session",
          "state",
          "connection",
          "last_verified_at",
          "last_observed_at"
        ],
        "properties": {
          "schema_version": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "event": {
            "$ref": "#/components/schemas/SessionLifecycleEventName"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time"
          },
          "destination_id": {
            "type": "string"
          },
          "session": {
            "type": "object",
            "required": [
              "id",
              "label",
              "provider",
              "server"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string",
                "nullable": true
              },
              "provider": {
                "type": "string"
              },
              "server": {
                "type": "string"
              }
            }
          },
          "state": {
            "type": "object",
            "required": [
              "previous",
              "current",
              "changed_at",
              "sequence"
            ],
            "properties": {
              "previous": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "connected",
                  "disconnected",
                  "unlinked",
                  "removed",
                  "unavailable",
                  null
                ]
              },
              "current": {
                "$ref": "#/components/schemas/SessionLifecycleState"
              },
              "changed_at": {
                "type": "string",
                "format": "date-time"
              },
              "sequence": {
                "type": "integer",
                "minimum": 1,
                "description": "Monotônica por sessão; pode conter saltos."
              }
            }
          },
          "connection": {
            "type": "object",
            "required": [
              "reason",
              "code",
              "is_logout",
              "intentional",
              "reconnect_expected",
              "requires_pairing"
            ],
            "properties": {
              "reason": {
                "type": "string",
                "nullable": true
              },
              "code": {
                "type": "number",
                "nullable": true
              },
              "is_logout": {
                "type": "boolean",
                "nullable": true
              },
              "intentional": {
                "type": "boolean",
                "nullable": true
              },
              "reconnect_expected": {
                "type": "boolean",
                "nullable": true,
                "description": "Indica intenção de reconexão; não garante sucesso."
              },
              "requires_pairing": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "last_verified_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Último evento de conexão do provider; heartbeat não renova essa prova."
          },
          "last_observed_at": {
            "type": "string",
            "format": "date-time",
            "description": "Observação local do worker; não é confirmação remota de conexão."
          }
        }
      },
      "VersionStatus": {
        "type": "object",
        "required": [
          "installed_version",
          "update_available",
          "status",
          "checked_at"
        ],
        "properties": {
          "installed_version": {
            "type": "string",
            "example": "4.0.19"
          },
          "latest_version": {
            "type": "string",
            "example": "4.0.19"
          },
          "update_available": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "current",
              "update_available",
              "unknown"
            ]
          },
          "checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "release_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "VoipCall": {
        "type": "object",
        "required": [
          "callId",
          "session"
        ],
        "properties": {
          "callId": {
            "type": "string"
          },
          "session": {
            "type": "string",
            "example": "5566999554300"
          },
          "direction": {
            "type": "string",
            "enum": [
              "incoming",
              "outgoing",
              "inbound",
              "outbound"
            ]
          },
          "peerJid": {
            "type": "string",
            "example": "5566996269251@s.whatsapp.net"
          },
          "callerPn": {
            "type": "string",
            "example": "5566996269251",
            "description": "Telefone confirmado, somente com dígitos. Um LID nunca é apresentado como telefone."
          },
          "callerName": {
            "type": "string",
            "maxLength": 128,
            "example": "João da Silva",
            "description": "Nome normalizado no diretório de contatos da própria sessão Zapo no início da chamada."
          },
          "callerNameSource": {
            "type": "string",
            "enum": [
              "display_name",
              "push_name",
              "username"
            ],
            "description": "Origem do nome apresentado no SIP e no WebRTC."
          },
          "extensionId": {
            "type": "string",
            "example": "1001"
          },
          "state": {
            "type": "string"
          },
          "streamId": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      },
      "VoipStartCallRequest": {
        "type": "object",
        "required": [
          "session",
          "peerJid",
          "extensionId"
        ],
        "properties": {
          "session": {
            "type": "string",
            "example": "5566999554300"
          },
          "peerJid": {
            "type": "string",
            "example": "5566996269251@s.whatsapp.net"
          },
          "extensionId": {
            "type": "string",
            "example": "1001",
            "description": "Ramal registrado que receberá a perna SIP da chamada."
          }
        }
      },
      "VoipAiSummary": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": false
          },
          "transcriptionProvider": {
            "type": "string",
            "enum": [
              "groq",
              "openai",
              "openrouter",
              "custom"
            ]
          },
          "summaryProvider": {
            "type": "string",
            "enum": [
              "groq",
              "openai",
              "openrouter",
              "custom"
            ]
          },
          "transcriptionBaseUrl": {
            "type": "string",
            "format": "uri"
          },
          "transcriptionApiKey": {
            "type": "string",
            "format": "password",
            "writeOnly": true,
            "description": "Valor vazio preserva o segredo já salvo."
          },
          "transcriptionModel": {
            "type": "string",
            "example": "whisper-large-v3"
          },
          "transcriptionLanguage": {
            "type": "string",
            "example": "pt"
          },
          "summaryBaseUrl": {
            "type": "string",
            "format": "uri"
          },
          "summaryApiKey": {
            "type": "string",
            "format": "password",
            "writeOnly": true,
            "description": "Valor vazio preserva o segredo já salvo."
          },
          "summaryModel": {
            "type": "string",
            "example": "openai/gpt-oss-20b"
          },
          "summaryPrompt": {
            "type": "string"
          },
          "includeTranscript": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "VoipCompany": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": "string",
            "example": "Matriz"
          },
          "timeZone": {
            "type": "string",
            "example": "America/Cuiaba"
          },
          "aiSummary": {
            "$ref": "#/components/schemas/VoipAiSummary"
          }
        }
      },
      "VoipChatwootRecording": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": false
          },
          "baseUrl": {
            "type": "string",
            "format": "uri"
          },
          "accountId": {
            "type": "string"
          },
          "inboxId": {
            "type": "string"
          },
          "apiAccessToken": {
            "type": "string",
            "format": "password",
            "writeOnly": true,
            "description": "Valor vazio preserva o segredo já salvo."
          },
          "privateNote": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "VoipAccount": {
        "type": "object",
        "required": [
          "label",
          "companyId",
          "phoneNumber"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "phoneNumber": {
            "type": "string",
            "example": "5566999554300"
          },
          "outboundAccessPrefix": {
            "type": "string",
            "default": "",
            "pattern": "^\\*[0-9]{1,6}\\*$|^$",
            "example": "*81*",
            "description": "Prefixo opcional para solicitar esta linha na discagem SIP/WebRTC. A linha continua sujeita ao roteamento avançado e o prefixo deve ser único na empresa."
          },
          "defaultDdi": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,2}$|^$",
            "example": "55",
            "description": "DDI sugerido pelo número brasileiro da linha quando ausente; editável. Vazio desativa o complemento deste campo."
          },
          "defaultDdd": {
            "type": "string",
            "pattern": "^[1-9][0-9]{1,3}$|^$",
            "example": "66",
            "description": "DDD sugerido pelo número brasileiro da linha quando ausente; editável. Usado para números locais de 8 ou 9 dígitos."
          },
          "maxConcurrentCalls": {
            "type": "integer",
            "minimum": 2,
            "maximum": 32,
            "default": 2,
            "description": "Limite simultâneo da linha Zapo, sem cadastro de dispositivo adicional."
          },
          "chatwootRecording": {
            "$ref": "#/components/schemas/VoipChatwootRecording"
          }
        }
      },
      "VoipLineGroup": {
        "type": "object",
        "required": [
          "label",
          "companyId"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "inboundSessionIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "outboundPrioritySessionIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "targetExtensionGroupIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "VoipExtensionGroup": {
        "type": "object",
        "required": [
          "label",
          "companyId"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "extensionIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "transferAudioFilename": {
            "type": "string",
            "readOnly": true
          },
          "transferAudioMime": {
            "type": "string",
            "readOnly": true
          }
        }
      },
      "VoipSession": {
        "type": "object",
        "required": [
          "label",
          "unoSession"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": "string"
          },
          "unoSession": {
            "type": "string",
            "example": "5566999554300"
          },
          "companyId": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "maxConcurrentCalls": {
            "type": "integer",
            "minimum": 2,
            "maximum": 32,
            "default": 2
          },
          "lineGroupIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inboundLineGroupIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "outboundLineGroupIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "routing": {
            "type": "object",
            "properties": {
              "strategy": {
                "type": "string",
                "enum": [
                  "sequential"
                ],
                "default": "sequential"
              },
              "ringTimeoutSeconds": {
                "type": "integer",
                "minimum": 1,
                "default": 20
              },
              "extensions": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "basicInboundEnabled": {
                "type": "boolean",
                "default": true,
                "description": "Quando false, impede apenas o toque recebido no ramal automático e exige ao menos um destino avançado válido."
              }
            }
          },
          "automaticExtensionId": {
            "type": "string",
            "readOnly": true,
            "description": "Ramal SIP/WebRTC gerenciado automaticamente para esta sessão Zapo."
          },
          "provisioningSource": {
            "type": "string",
            "enum": [
              "zapo_auto"
            ],
            "readOnly": true
          }
        }
      },
      "VoipExtension": {
        "type": "object",
        "required": [
          "displayName",
          "username"
        ],
        "properties": {
          "defaultDdi": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,2}$|^$",
            "description": "Sobrescreve o DDI da linha escolhida. Vazio ou ausente herda da linha."
          },
          "defaultDdd": {
            "type": "string",
            "pattern": "^[1-9][0-9]{1,3}$|^$",
            "description": "Sobrescreve o DDD da linha escolhida. Vazio ou ausente herda da linha."
          },
          "id": {
            "type": "string",
            "readOnly": true
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "type": {
            "type": "string",
            "enum": [
              "webrtc",
              "sip",
              "both"
            ],
            "default": "both"
          },
          "displayName": {
            "type": "string"
          },
          "username": {
            "type": "string",
            "example": "1001"
          },
          "password": {
            "type": "string",
            "format": "password",
            "writeOnly": true,
            "description": "Valor vazio preserva a senha já salva."
          },
          "companyId": {
            "type": "string"
          },
          "extensionGroupIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "extensionGroupDistances": {
            "type": "object",
            "description": "Prioridade por grupo; o menor valor toca primeiro.",
            "additionalProperties": {
              "type": "integer",
              "minimum": 1
            }
          },
          "provisioningSource": {
            "type": "string",
            "enum": [
              "zapo_auto"
            ],
            "readOnly": true,
            "description": "Presente nos ramais criados e reconciliados automaticamente pela sessão Zapo."
          }
        }
      },
      "VoipConfigResponse": {
        "type": "object",
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "VoipRegistration": {
        "type": "object",
        "required": [
          "registrationId"
        ],
        "properties": {
          "registrationId": {
            "type": "string"
          },
          "id": {
            "type": "string",
            "description": "ID do ramal associado."
          },
          "username": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "transport": {
            "type": "string",
            "enum": [
              "webrtc",
              "sip_rtp"
            ]
          },
          "contact": {
            "type": "string"
          },
          "userAgent": {
            "type": "string"
          },
          "expiresIn": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": true
      },
      "VoipRegistrations": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "webrtc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipRegistration"
            }
          },
          "sipRtp": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipRegistration"
            }
          }
        }
      },
      "VoipZapoLine": {
        "type": "object",
        "required": [
          "session",
          "connected",
          "automatic",
          "advancedRoutingConfigured"
        ],
        "properties": {
          "session": {
            "type": "string",
            "example": "5566999554300"
          },
          "sourceId": {
            "type": "string"
          },
          "connected": {
            "type": "boolean"
          },
          "companyId": {
            "type": "string"
          },
          "companyLabel": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "sessionId": {
            "type": "string"
          },
          "maxConcurrentCalls": {
            "type": "integer",
            "minimum": 2,
            "maximum": 32,
            "default": 2
          },
          "automatic": {
            "$ref": "#/components/schemas/VoipAutomaticExtension"
          },
          "advancedRoutingConfigured": {
            "type": "boolean",
            "description": "Indica se a linha também possui destinos no roteamento avançado."
          }
        },
        "additionalProperties": true
      },
      "VoipAutomaticExtension": {
        "type": "object",
        "required": [
          "extensionId",
          "username",
          "status",
          "registrationCount",
          "freeRegistrationCount",
          "busyRegistrationCount",
          "transports",
          "basicInboundEnabled"
        ],
        "properties": {
          "extensionId": {
            "type": "string"
          },
          "username": {
            "type": "string",
            "example": "5566999554300"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "offline"
            ]
          },
          "registrationCount": {
            "type": "integer",
            "minimum": 0
          },
          "freeRegistrationCount": {
            "type": "integer",
            "minimum": 0
          },
          "busyRegistrationCount": {
            "type": "integer",
            "minimum": 0
          },
          "transports": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "sip",
                "webrtc"
              ]
            }
          },
          "basicInboundEnabled": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "VoipHistoryItem": {
        "type": "object",
        "required": [
          "id",
          "callId",
          "direction",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "callId": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound",
              "internal"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "routing",
              "ringing",
              "active",
              "completed",
              "missed",
              "failed",
              "cancelled"
            ]
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationSeconds": {
            "type": "integer",
            "minimum": 0
          },
          "companyId": {
            "type": "string"
          },
          "companyLabel": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "accountLabel": {
            "type": "string"
          },
          "extensionId": {
            "type": "string"
          },
          "extensionLabel": {
            "type": "string"
          },
          "remoteName": {
            "type": "string",
            "maxLength": 128,
            "description": "Fotografia do nome apresentado no começo da chamada; mudanças futuras no contato não alteram o histórico."
          },
          "remoteNameSource": {
            "type": "string",
            "enum": [
              "display_name",
              "push_name",
              "username"
            ]
          },
          "remoteNumber": {
            "type": "string",
            "description": "Telefone confirmado, somente com dígitos; nunca contém LID."
          },
          "remoteJid": {
            "type": "string",
            "description": "JID ou LID original preservado somente para auditoria."
          },
          "recordingStatus": {
            "type": "string",
            "enum": [
              "disabled",
              "recording",
              "processing",
              "available",
              "failed"
            ]
          },
          "recordingMime": {
            "type": "string"
          },
          "recordingSizeBytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "aiSummaryStatus": {
            "type": "string",
            "enum": [
              "disabled",
              "queued",
              "processing",
              "completed",
              "failed"
            ]
          },
          "aiTranscriptText": {
            "type": "string"
          },
          "aiSummaryText": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "VoipHistoryPage": {
        "type": "object",
        "required": [
          "items",
          "total",
          "page",
          "pageSize",
          "totalPages"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipHistoryItem"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "totalPages": {
            "type": "integer",
            "minimum": 1
          },
          "search": {
            "type": "string"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "VoipRecordingSettings": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "enum": [
              "local",
              "s3"
            ]
          },
          "localDir": {
            "type": "string",
            "example": "/home/u/app/data/recordings"
          },
          "format": {
            "type": "string",
            "enum": [
              "wav",
              "mp3",
              "gsm"
            ]
          },
          "stereo": {
            "type": "boolean"
          },
          "deleteLocalAfterUpload": {
            "type": "boolean"
          },
          "s3Endpoint": {
            "type": "string"
          },
          "s3Region": {
            "type": "string",
            "default": "auto"
          },
          "s3Bucket": {
            "type": "string"
          },
          "s3AccessKeyId": {
            "type": "string"
          },
          "s3SecretAccessKey": {
            "type": "string",
            "format": "password",
            "writeOnly": true,
            "description": "Valor vazio preserva o segredo já salvo."
          },
          "s3ForcePathStyle": {
            "type": "boolean"
          },
          "s3PublicBaseUrl": {
            "type": "string"
          },
          "s3PresignTtlSeconds": {
            "type": "integer",
            "minimum": 1,
            "default": 3600
          },
          "retentionDays": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          }
        }
      },
      "VoipRecordingSummary": {
        "type": "object",
        "properties": {
          "recording": {
            "$ref": "#/components/schemas/VoipRecordingSettings"
          },
          "accounts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "accountId": {
                  "type": "string"
                },
                "accountLabel": {
                  "type": "string"
                },
                "companyLabel": {
                  "type": "string"
                },
                "phoneNumber": {
                  "type": "string"
                },
                "count": {
                  "type": "integer",
                  "minimum": 0
                },
                "sizeBytes": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 0
                }
              }
            }
          }
        }
      },
      "VoipExtensionCredentials": {
        "type": "object",
        "properties": {
          "extensionId": {
            "type": "string"
          },
          "companyId": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "password": {
            "type": "string",
            "format": "password"
          },
          "type": {
            "type": "string",
            "enum": [
              "webrtc",
              "sip",
              "both"
            ]
          },
          "sipUri": {
            "type": "string",
            "example": "sip:1001@sip.seudominio.com.br"
          },
          "sip": {
            "type": "object",
            "additionalProperties": true
          },
          "webrtc": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "VoipResolveInboundRequest": {
        "type": "object",
        "required": [
          "sessionId"
        ],
        "properties": {
          "sessionId": {
            "type": "string",
            "example": "5566999554300"
          },
          "callId": {
            "type": "string",
            "description": "Se omitido",
            "o serviço gera um ID de simulação.": null
          }
        }
      },
      "VoipResolveOutboundRequest": {
        "type": "object",
        "required": [
          "extensionId",
          "target"
        ],
        "properties": {
          "extensionId": {
            "type": "string",
            "example": "1001"
          },
          "target": {
            "type": "string",
            "example": "5566996269251"
          },
          "callId": {
            "type": "string",
            "description": "ID opcional usado somente no histórico da simulação."
          }
        }
      },
      "VoipRouterLock": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "callId": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "extensionId": {
            "type": "string"
          },
          "targetNumber": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "VoipRouterResult": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "kind": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "lock": {
            "$ref": "#/components/schemas/VoipRouterLock"
          },
          "session": {
            "$ref": "#/components/schemas/VoipSession"
          },
          "extension": {
            "$ref": "#/components/schemas/VoipExtension"
          },
          "account": {
            "$ref": "#/components/schemas/VoipAccount"
          },
          "normalizedTarget": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "VoipBootstrap": {
        "type": "object",
        "properties": {
          "bridges": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipCall"
            }
          },
          "companies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipCompany"
            }
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipAccount"
            }
          },
          "lineGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipLineGroup"
            }
          },
          "extensionGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipExtensionGroup"
            }
          },
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipSession"
            }
          },
          "extensions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipExtension"
            }
          },
          "registrations": {
            "$ref": "#/components/schemas/VoipRegistrations"
          },
          "zapoLines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoipZapoLine"
            }
          },
          "history": {
            "$ref": "#/components/schemas/VoipHistoryPage"
          },
          "recording": {
            "$ref": "#/components/schemas/VoipRecordingSettings"
          },
          "recordingSummary": {
            "$ref": "#/components/schemas/VoipRecordingSummary"
          },
          "router": {
            "type": "object",
            "properties": {
              "locks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/VoipRouterLock"
                }
              }
            }
          }
        },
        "additionalProperties": true
      },
      "Error400": {
        "type": "object",
        "required": [
          "error",
          "status",
          "message"
        ],
        "properties": {
          "error_code": {
            "type": "string",
            "description": "Código simbólico estável, quando disponível; independente do idioma da mensagem."
          },
          "error": {
            "type": "object",
            "required": [
              "message",
              "type",
              "code"
            ],
            "properties": {
              "message": {
                "type": "string"
              },
              "error_code": {
                "type": "string",
                "description": "Código simbólico preservado no envelope de erro; o texto usa pt-BR por padrão."
              },
              "type": {
                "type": "string",
                "example": "GraphMethodException"
              },
              "code": {
                "type": "integer",
                "example": 131000
              },
              "error_subcode": {
                "type": "integer"
              },
              "fbtrace_id": {
                "type": "string"
              }
            }
          },
          "status": {
            "type": "string",
            "example": "error"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "RegisterConfig": {
        "description": "Configuração da sessão. Campos variam por provedor.",
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "authToken": {
            "type": "string"
          },
          "provider": {
            "type": "string",
            "enum": [
              "zapo"
            ],
            "default": "zapo",
            "description": "Motor WhatsApp da sessão. O caminho documentado e suportado é Zapo."
          },
          "connectionType": {
            "type": "string",
            "enum": [
              "qrcode",
              "pairing_code"
            ],
            "description": "Forma de pareamento. Em uma sessão Zapo já registrada, este valor permanece bloqueado no modo atual mesmo quando a sessão está offline. Para trocar o modo, execute deregister e registre a sessão novamente."
          },
          "zapoWebClientProfile": {
            "type": "string",
            "enum": [
              "default",
              "wa_personal",
              "wa_business"
            ],
            "default": "default",
            "description": "Identidade Web usada no pareamento de uma nova sessão Zapo. default preserva o comportamento atual da Zapo. wa_personal anuncia ANDROID e wa_business anuncia SMB_ANDROID; ambos usam DeviceProps ANDROID_TABLET e o campo de plataforma e no QR. Os perfis Android são experimentais, aceitos somente com connectionType=qrcode e ficam bloqueados após o primeiro registro até o deregister."
          }
        }
      },
      "SessionsList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "display_phone_number": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "PhoneInfo": {
        "type": "object",
        "properties": {
          "display_phone_number": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "message_templates": {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "MessageCommon": {
        "type": "object",
        "required": [
          "messaging_product",
          "to",
          "type"
        ],
        "properties": {
          "messaging_product": {
            "type": "string",
            "example": "whatsapp"
          },
          "to": {
            "type": "string",
            "description": "Número destino (ou status@broadcast)"
          },
          "type": {
            "type": "string"
          },
          "context": {
            "type": "object",
            "description": "Responde ou cita uma mensagem anterior.",
            "required": [
              "message_id"
            ],
            "properties": {
              "message_id": {
                "type": "string",
                "minLength": 1,
                "description": "ID retornado pela UnoAPI para a mensagem citada."
              }
            }
          }
        }
      },
      "MessageStatusBroadcast": {
        "description": "Publica imagem ou vídeo no Status/Stories. `statusJidList` limita os destinatários; quando omitido, a UnoAPI usa os contatos disponíveis para a sessão.",
        "oneOf": [
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/MessageImage"
              },
              {
                "type": "object",
                "properties": {
                  "to": {
                    "const": "status@broadcast"
                  },
                  "statusJidList": {
                    "type": "array",
                    "nullable": true,
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "minLength": 8
                    }
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "statusJidList": {
                        "type": "array",
                        "nullable": true,
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "minLength": 8
                        }
                      }
                    }
                  }
                }
              }
            ]
          },
          {
            "allOf": [
              {
                "$ref": "#/components/schemas/MessageVideo"
              },
              {
                "type": "object",
                "properties": {
                  "to": {
                    "const": "status@broadcast"
                  },
                  "statusJidList": {
                    "type": "array",
                    "nullable": true,
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "minLength": 8
                    }
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "statusJidList": {
                        "type": "array",
                        "nullable": true,
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "minLength": 8
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        ]
      },
      "MessageText": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "text"
            ],
            "properties": {
              "type": {
                "const": "text"
              },
              "text": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string"
                  },
                  "mentionAll": {
                    "type": "boolean",
                    "description": "Opcional. Se true, menciona todos os participantes. Em grupos, `@all`/`@todos` no body também ativa automaticamente."
                  },
                  "mentions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Opcional. Lista de números ou JIDs para menção. Em grupos, `@<telefone_valido>` no body também é extraído automaticamente."
                  }
                }
              },
              "mentionAll": {
                "type": "boolean",
                "description": "Atalho opcional equivalente a text.mentionAll"
              },
              "mentions": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Atalho opcional equivalente a text.mentions"
              }
            }
          }
        ]
      },
      "MessageLocation": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "location"
            ],
            "properties": {
              "type": {
                "const": "location"
              },
              "location": {
                "type": "object",
                "required": [
                  "latitude",
                  "longitude"
                ],
                "description": "Localização estática. Nome e endereço são opcionais. Aceita números ou strings decimais; coordenadas são normalizadas antes da fila. Não compartilha localização em tempo real.",
                "properties": {
                  "latitude": {
                    "description": "Latitude entre -90 e 90, inclusive; zero é válido.",
                    "oneOf": [
                      {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      {
                        "type": "string",
                        "pattern": "^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$",
                        "example": "-15.601"
                      }
                    ]
                  },
                  "longitude": {
                    "description": "Longitude entre -180 e 180, inclusive; zero é válido.",
                    "oneOf": [
                      {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      },
                      {
                        "type": "string",
                        "pattern": "^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$",
                        "example": "-56.0974"
                      }
                    ]
                  },
                  "name": {
                    "type": "string"
                  },
                  "address": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      },
      "MessageEdit": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "context",
              "text"
            ],
            "properties": {
              "type": {
                "const": "message_edit"
              },
              "context": {
                "type": "object",
                "required": [
                  "message_id"
                ],
                "properties": {
                  "message_id": {
                    "type": "string",
                    "description": "ID Unoapi da mensagem original enviada pela conta conectada. A Unoapi resolve o ID para a key do provider; na Zapo usa editKey com id e participante opcional."
                  }
                }
              },
              "text": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string"
                  },
                  "mentions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Opcional. Lista de números ou JIDs para menção no texto editado."
                  }
                }
              },
              "mentions": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Atalho opcional equivalente a text.mentions."
              }
            }
          }
        ]
      },
      "MessageImage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "image"
            ],
            "properties": {
              "type": {
                "const": "image"
              },
              "image": {
                "type": "object",
                "description": "Use somente uma origem, `link` ou `base64`.",
                "oneOf": [
                  {
                    "required": [
                      "link"
                    ]
                  },
                  {
                    "required": [
                      "base64"
                    ]
                  }
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "base64": {
                    "type": "string",
                    "writeOnly": true,
                    "description": "Extensão ViperConnect. Aceita Base64 puro ou Data URI. Para Base64 puro, informe mime_type."
                  },
                  "caption": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "image/jpeg"
                  },
                  "view_once": {
                    "type": "boolean",
                    "default": false,
                    "description": "Extensão ViperConnect/Zapo: visualização única. Aceita somente booleano; omitido ou false mantém envio normal. Mapeado para options.viewOnce da Zapo."
                  }
                }
              }
            }
          }
        ]
      },
      "MessageVideo": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "video"
            ],
            "properties": {
              "type": {
                "const": "video"
              },
              "video": {
                "type": "object",
                "description": "Use somente uma origem, `link` ou `base64`.",
                "oneOf": [
                  {
                    "required": [
                      "link"
                    ]
                  },
                  {
                    "required": [
                      "base64"
                    ]
                  }
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "base64": {
                    "type": "string",
                    "writeOnly": true,
                    "description": "Extensão ViperConnect. Aceita Base64 puro ou Data URI. Para Base64 puro, informe mime_type."
                  },
                  "caption": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "video/mp4"
                  },
                  "view_once": {
                    "type": "boolean",
                    "default": false,
                    "description": "Extensão ViperConnect/Zapo: visualização única; preservada durante a preparação do vídeo. Aceita somente booleano."
                  },
                  "quality": {
                    "type": "string",
                    "enum": [
                      "hd",
                      "sd"
                    ],
                    "default": "hd",
                    "description": "Extensão Zapo: hd até 720p/CRF23, sd até 480p/CRF27, até 30 FPS. MP4 faststart conforme é reutilizado sem FFmpeg; sem faststart recebe remux. Conversão gera statuses[].warnings com VIDEO_TRANSCODED. Teto operacional de saída configurável (256 MiB padrão), sem redução automática para 15 MiB. Não garante selo HD no WhatsApp."
                  }
                }
              }
            }
          }
        ]
      },
      "MessageSticker": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "sticker"
            ],
            "properties": {
              "type": {
                "const": "sticker"
              },
              "sticker": {
                "type": "object",
                "description": "Use somente uma origem, `link` ou `base64`.",
                "oneOf": [
                  {
                    "required": [
                      "link"
                    ]
                  },
                  {
                    "required": [
                      "base64"
                    ]
                  }
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri",
                    "description": "PNG/JPG/GIF are auto-converted to WEBP before sending"
                  },
                  "base64": {
                    "type": "string",
                    "writeOnly": true,
                    "description": "Extensão ViperConnect. Figurinha em Base64 ou Data URI com mime_type image/webp."
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "image/webp"
                  }
                }
              }
            }
          }
        ]
      },
      "MessageAudio": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "audio"
            ],
            "properties": {
              "type": {
                "const": "audio"
              },
              "audio": {
                "type": "object",
                "description": "Use somente uma origem, `link` ou `base64`.",
                "oneOf": [
                  {
                    "required": [
                      "link"
                    ]
                  },
                  {
                    "required": [
                      "base64"
                    ]
                  }
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "base64": {
                    "type": "string",
                    "writeOnly": true,
                    "description": "Extensão ViperConnect. Aceita Base64 puro ou Data URI. Para Base64 puro, informe mime_type."
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "audio/ogg"
                  },
                  "view_once": {
                    "type": "boolean",
                    "default": false,
                    "description": "Extensão ViperConnect/Zapo: áudio de reprodução única. Independente de ptt. Aceita somente booleano."
                  },
                  "ptt": {
                    "type": "boolean",
                    "description": "Envia como mensagem de voz quando `true`."
                  }
                }
              }
            }
          }
        ]
      },
      "MessageDocument": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "document"
            ],
            "properties": {
              "type": {
                "const": "document"
              },
              "document": {
                "type": "object",
                "description": "Use somente uma origem, `link` ou `base64`.",
                "oneOf": [
                  {
                    "required": [
                      "link"
                    ]
                  },
                  {
                    "required": [
                      "base64"
                    ]
                  }
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "base64": {
                    "type": "string",
                    "writeOnly": true,
                    "description": "Extensão ViperConnect. Aceita Base64 puro ou Data URI. Para Base64 puro, informe mime_type."
                  },
                  "filename": {
                    "type": "string"
                  },
                  "caption": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "application/pdf"
                  }
                }
              }
            }
          }
        ]
      },
      "MessageContacts": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "contacts"
            ],
            "properties": {
              "type": {
                "const": "contacts"
              },
              "contacts": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "object",
                  "required": [
                    "name",
                    "phones"
                  ],
                  "properties": {
                    "name": {
                      "type": "object",
                      "required": [
                        "formatted_name"
                      ],
                      "properties": {
                        "formatted_name": {
                          "type": "string"
                        }
                      }
                    },
                    "phones": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "object",
                        "required": [
                          "phone"
                        ],
                        "properties": {
                          "wa_id": {
                            "type": "string"
                          },
                          "phone": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageReaction": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "reaction"
            ],
            "properties": {
              "type": {
                "const": "reaction"
              },
              "reaction": {
                "type": "object",
                "required": [
                  "message_id",
                  "emoji"
                ],
                "properties": {
                  "message_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "ID UnoAPI da mensagem que receberá ou removerá a reação."
                  },
                  "emoji": {
                    "type": "string",
                    "description": "Emoji da reação. Envie string vazia para remover a reação."
                  }
                }
              }
            }
          }
        ]
      },
      "MessagePoll": {
        "description": "Cria uma enquete nativa.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "poll"
            ],
            "properties": {
              "type": {
                "const": "poll"
              },
              "poll": {
                "type": "object",
                "required": [
                  "name",
                  "options"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Pergunta exibida na enquete."
                  },
                  "options": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "oneOf": [
                        {
                          "type": "string",
                          "minLength": 1
                        },
                        {
                          "type": "object",
                          "required": [
                            "name"
                          ],
                          "properties": {
                            "name": {
                              "type": "string",
                              "minLength": 1
                            }
                          }
                        }
                      ]
                    }
                  },
                  "selectable_count": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Quantidade máxima de opções selecionáveis."
                  },
                  "allow_add_option": {
                    "type": "boolean",
                    "default": false
                  },
                  "hide_participant_name": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        ]
      },
      "MessagePollVote": {
        "description": "Vota em uma enquete recebida ou enviada anteriormente.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "poll_vote"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "poll_vote",
                  "poll-vote"
                ]
              },
              "poll_vote": {
                "type": "object",
                "required": [
                  "message_id",
                  "selected_options"
                ],
                "properties": {
                  "message_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "ID UnoAPI da mensagem que criou a enquete."
                  },
                  "selected_options": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageInteractiveButtons": {
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "button"
                  },
                  "header": {
                    "$ref": "#/components/schemas/InteractiveHeader"
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "buttons"
                    ],
                    "properties": {
                      "buttons": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "object",
                          "required": [
                            "type",
                            "reply"
                          ],
                          "properties": {
                            "type": {
                              "const": "reply"
                            },
                            "reply": {
                              "type": "object",
                              "required": [
                                "id",
                                "title"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "title": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "InteractiveHeader": {
        "description": "Cabeçalho textual ou de mídia. Listas aceitam somente texto.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type",
              "text"
            ],
            "properties": {
              "type": {
                "const": "text"
              },
              "text": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "image"
            ],
            "properties": {
              "type": {
                "const": "image"
              },
              "text": {
                "type": "string"
              },
              "image": {
                "type": "object",
                "required": [
                  "link"
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "image/jpeg"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "video"
            ],
            "properties": {
              "type": {
                "const": "video"
              },
              "text": {
                "type": "string"
              },
              "video": {
                "type": "object",
                "required": [
                  "link"
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "video/mp4"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "document"
            ],
            "properties": {
              "type": {
                "const": "document"
              },
              "text": {
                "type": "string"
              },
              "document": {
                "type": "object",
                "required": [
                  "link"
                ],
                "properties": {
                  "link": {
                    "type": "string",
                    "format": "uri"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime_type": {
                    "type": "string",
                    "example": "application/pdf"
                  }
                }
              }
            }
          }
        ]
      },
      "MessageInteractiveCtaButtons": {
        "description": "Botões de ação nativos da Zapo. `cta_url` abre um endereço, `cta_call` inicia uma ligação e `cta_copy` copia um código.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "button"
                  },
                  "header": {
                    "$ref": "#/components/schemas/InteractiveHeader"
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "buttons"
                    ],
                    "properties": {
                      "buttons": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "required": [
                                "type",
                                "url"
                              ],
                              "properties": {
                                "type": {
                                  "const": "cta_url"
                                },
                                "url": {
                                  "type": "object",
                                  "required": [
                                    "title",
                                    "link"
                                  ],
                                  "properties": {
                                    "title": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "link": {
                                      "type": "string",
                                      "format": "uri"
                                    },
                                    "merchant_url": {
                                      "type": "string",
                                      "format": "uri",
                                      "description": "Opcional; padrao igual a link."
                                    },
                                    "webview_presentation": {
                                      "type": "string",
                                      "enum": [
                                        "full"
                                      ],
                                      "description": "Solicita WebView. Abertura interna validada no lab em 03/10/2026 com interaction=true; nao garante todos os clientes."
                                    },
                                    "webview_interaction": {
                                      "type": "boolean",
                                      "description": "Experimental Zapo. Encaminhado sem conversao; omissao preserva comportamento anterior. Nao cria callback do formulario."
                                    }
                                  }
                                }
                              }
                            },
                            {
                              "type": "object",
                              "required": [
                                "type",
                                "call"
                              ],
                              "properties": {
                                "type": {
                                  "const": "cta_call"
                                },
                                "call": {
                                  "type": "object",
                                  "required": [
                                    "title",
                                    "phone_number"
                                  ],
                                  "properties": {
                                    "title": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "phone_number": {
                                      "type": "string",
                                      "minLength": 1
                                    }
                                  }
                                }
                              }
                            },
                            {
                              "type": "object",
                              "required": [
                                "type",
                                "copy_code"
                              ],
                              "properties": {
                                "type": {
                                  "const": "cta_copy"
                                },
                                "copy_code": {
                                  "type": "object",
                                  "required": [
                                    "title",
                                    "code"
                                  ],
                                  "properties": {
                                    "title": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "code": {
                                      "type": "string",
                                      "minLength": 1
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageInteractiveList": {
        "description": "Lista de seleção única. Na Zapo, a UnoAPI converte este contrato para o `listMessage` raw documentado, usando `rows[].id` como `rowId`. Quando o contato seleciona uma linha, o mesmo ID retorna no webhook em `messages[].interactive.list_reply.id`.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "list"
                  },
                  "header": {
                    "type": "object",
                    "required": [
                      "type",
                      "text"
                    ],
                    "description": "Cabeçalho textual opcional. Lista Zapo não aceita cabeçalho de mídia.",
                    "properties": {
                      "type": {
                        "const": "text"
                      },
                      "text": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "description": "Texto principal exibido antes do botão da lista."
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string",
                        "description": "Rodapé opcional."
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "button",
                      "sections"
                    ],
                    "properties": {
                      "button": {
                        "type": "string",
                        "minLength": 1,
                        "description": "Texto do botão que abre a lista."
                      },
                      "sections": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "object",
                          "required": [
                            "title",
                            "rows"
                          ],
                          "properties": {
                            "title": {
                              "type": "string",
                              "description": "Título da seção."
                            },
                            "rows": {
                              "type": "array",
                              "minItems": 1,
                              "items": {
                                "type": "object",
                                "required": [
                                  "id",
                                  "title"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Identificador estável da opção. Na Zapo vira `rowId` e retorna como `interactive.list_reply.id`."
                                  },
                                  "title": {
                                    "type": "string",
                                    "minLength": 1,
                                    "description": "Texto principal da opção."
                                  },
                                  "description": {
                                    "type": "string",
                                    "description": "Descrição opcional da opção."
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "type": "list",
                  "header": {
                    "type": "text",
                    "text": "Menu"
                  },
                  "body": {
                    "text": "Escolha uma opção"
                  },
                  "footer": {
                    "text": "Unoapi"
                  },
                  "action": {
                    "button": "Ver opções",
                    "sections": [
                      {
                        "title": "Planos",
                        "rows": [
                          {
                            "id": "plan_basic",
                            "title": "Básico",
                            "description": "R$ 10"
                          },
                          {
                            "id": "plan_pro",
                            "title": "Pro",
                            "description": "R$ 20"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        ]
      },
      "MessageInteractiveCarousel": {
        "description": "Carrossel nativo com 2 a 10 cartões. Cada cartão pode usar cabeçalho textual ou de mídia e botões de resposta, URL, ligação ou cópia.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "carousel"
                  },
                  "header": {
                    "$ref": "#/components/schemas/InteractiveHeader"
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "carousel"
                    ],
                    "properties": {
                      "carousel": {
                        "type": "object",
                        "required": [
                          "cards"
                        ],
                        "properties": {
                          "cards": {
                            "type": "array",
                            "minItems": 2,
                            "maxItems": 10,
                            "items": {
                              "type": "object",
                              "required": [
                                "header",
                                "body",
                                "action"
                              ],
                              "properties": {
                                "header": {
                                  "$ref": "#/components/schemas/InteractiveHeader"
                                },
                                "body": {
                                  "type": "object",
                                  "required": [
                                    "text"
                                  ],
                                  "properties": {
                                    "text": {
                                      "type": "string",
                                      "minLength": 1
                                    }
                                  }
                                },
                                "footer": {
                                  "type": "object",
                                  "properties": {
                                    "text": {
                                      "type": "string"
                                    }
                                  }
                                },
                                "action": {
                                  "type": "object",
                                  "required": [
                                    "buttons"
                                  ],
                                  "properties": {
                                    "buttons": {
                                      "type": "array",
                                      "minItems": 1,
                                      "items": {
                                        "oneOf": [
                                          {
                                            "type": "object",
                                            "required": [
                                              "type",
                                              "reply"
                                            ],
                                            "properties": {
                                              "type": {
                                                "const": "reply"
                                              },
                                              "reply": {
                                                "type": "object",
                                                "required": [
                                                  "id",
                                                  "title"
                                                ],
                                                "properties": {
                                                  "id": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  },
                                                  "title": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  }
                                                }
                                              }
                                            }
                                          },
                                          {
                                            "type": "object",
                                            "required": [
                                              "type",
                                              "url"
                                            ],
                                            "properties": {
                                              "type": {
                                                "const": "cta_url"
                                              },
                                              "url": {
                                                "type": "object",
                                                "required": [
                                                  "title",
                                                  "link"
                                                ],
                                                "properties": {
                                                  "title": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  },
                                                  "link": {
                                                    "type": "string",
                                                    "format": "uri"
                                                  },
                                                  "merchant_url": {
                                                    "type": "string",
                                                    "format": "uri"
                                                  },
                                                  "webview_presentation": {
                                                    "type": "string",
                                                    "enum": [
                                                      "full"
                                                    ],
                                                    "description": "Experimental Zapo; abertura interna nao garantida."
                                                  },
                                                  "webview_interaction": {
                                                    "type": "boolean",
                                                    "description": "Dica experimental; nao cria callback do formulario."
                                                  }
                                                }
                                              }
                                            }
                                          },
                                          {
                                            "type": "object",
                                            "required": [
                                              "type",
                                              "call"
                                            ],
                                            "properties": {
                                              "type": {
                                                "const": "cta_call"
                                              },
                                              "call": {
                                                "type": "object",
                                                "required": [
                                                  "title",
                                                  "phone_number"
                                                ],
                                                "properties": {
                                                  "title": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  },
                                                  "phone_number": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  }
                                                }
                                              }
                                            }
                                          },
                                          {
                                            "type": "object",
                                            "required": [
                                              "type",
                                              "copy_code"
                                            ],
                                            "properties": {
                                              "type": {
                                                "const": "cta_copy"
                                              },
                                              "copy_code": {
                                                "type": "object",
                                                "required": [
                                                  "title",
                                                  "code"
                                                ],
                                                "properties": {
                                                  "title": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  },
                                                  "code": {
                                                    "type": "string",
                                                    "minLength": 1
                                                  }
                                                }
                                              }
                                            }
                                          }
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "PaymentAmount": {
        "type": "object",
        "required": [
          "value",
          "offset"
        ],
        "properties": {
          "value": {
            "type": "integer",
            "minimum": 0,
            "description": "Valor na menor unidade definida por `offset`."
          },
          "offset": {
            "type": "integer",
            "minimum": 1,
            "example": 100
          }
        }
      },
      "PaymentSetting": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type",
              "pix_static_code"
            ],
            "properties": {
              "type": {
                "const": "pix_static_code"
              },
              "pix_static_code": {
                "type": "object",
                "required": [
                  "merchant_name",
                  "key",
                  "key_type"
                ],
                "properties": {
                  "merchant_name": {
                    "type": "string"
                  },
                  "key": {
                    "type": "string"
                  },
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "CPF",
                      "CNPJ",
                      "EMAIL",
                      "PHONE",
                      "EVP"
                    ]
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "pix_dynamic_code"
            ],
            "properties": {
              "type": {
                "const": "pix_dynamic_code"
              },
              "pix_dynamic_code": {
                "type": "object",
                "required": [
                  "code",
                  "merchant_name",
                  "key",
                  "key_type"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Código PIX copia e cola completo."
                  },
                  "merchant_name": {
                    "type": "string"
                  },
                  "key": {
                    "type": "string"
                  },
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "CPF",
                      "CNPJ",
                      "EMAIL",
                      "PHONE",
                      "EVP"
                    ]
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "payment_link"
            ],
            "properties": {
              "type": {
                "const": "payment_link"
              },
              "payment_link": {
                "type": "object",
                "required": [
                  "uri"
                ],
                "properties": {
                  "uri": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "boleto"
            ],
            "properties": {
              "type": {
                "const": "boleto"
              },
              "boleto": {
                "type": "object",
                "required": [
                  "digitable_line"
                ],
                "properties": {
                  "digitable_line": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          },
          {
            "type": "object",
            "description": "Disponível somente para contas habilitadas para pagamento em um clique.",
            "required": [
              "type",
              "offsite_card_pay"
            ],
            "properties": {
              "type": {
                "const": "offsite_card_pay"
              },
              "offsite_card_pay": {
                "type": "object",
                "required": [
                  "last_four_digits",
                  "credential_id"
                ],
                "properties": {
                  "last_four_digits": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 4
                  },
                  "credential_id": {
                    "type": "string",
                    "minLength": 1
                  }
                }
              }
            }
          }
        ]
      },
      "PaymentOrder": {
        "type": "object",
        "required": [
          "status",
          "items",
          "subtotal"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "partially_shipped",
              "shipped",
              "completed",
              "canceled"
            ]
          },
          "tax": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PaymentAmount"
              },
              {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "shipping": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PaymentAmount"
              },
              {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "discount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PaymentAmount"
              },
              {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "name",
                "amount",
                "quantity"
              ],
              "properties": {
                "retailer_id": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "minLength": 1
                },
                "amount": {
                  "$ref": "#/components/schemas/PaymentAmount"
                },
                "quantity": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "subtotal": {
            "$ref": "#/components/schemas/PaymentAmount"
          }
        }
      },
      "MessagePaymentRequest": {
        "description": "Solicitação curta de PIX estático pelo fluxo Zapo `payment_info`. O envelope legado de PIX dinâmico permanece aceito, mas é convertido internamente para `order_details/review_and_pay` e não deve ser usado por novas integrações.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "button"
                  },
                  "body": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "buttons"
                    ],
                    "properties": {
                      "buttons": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 1,
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "required": [
                                "type",
                                "payment_setting"
                              ],
                              "properties": {
                                "type": {
                                  "const": "payment_request"
                                },
                                "payment_setting": {
                                  "type": "object",
                                  "required": [
                                    "type",
                                    "pix_static_code"
                                  ],
                                  "properties": {
                                    "type": {
                                      "const": "pix_static_code"
                                    },
                                    "pix_static_code": {
                                      "type": "object",
                                      "required": [
                                        "merchant_name",
                                        "key",
                                        "key_type"
                                      ],
                                      "properties": {
                                        "merchant_name": {
                                          "type": "string"
                                        },
                                        "key": {
                                          "type": "string"
                                        },
                                        "key_type": {
                                          "type": "string",
                                          "enum": [
                                            "CPF",
                                            "CNPJ",
                                            "EMAIL",
                                            "PHONE",
                                            "EVP"
                                          ]
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            {
                              "type": "object",
                              "deprecated": true,
                              "description": "Compatibilidade com o envelope antigo. A Uno converte este payload para o pedido simplificado `order_details/review_and_pay`.",
                              "required": [
                                "type",
                                "payment_request"
                              ],
                              "properties": {
                                "type": {
                                  "const": "payment_request"
                                },
                                "payment_request": {
                                  "type": "object",
                                  "required": [
                                    "type",
                                    "payment_type",
                                    "payment_settings",
                                    "currency",
                                    "total_amount"
                                  ],
                                  "properties": {
                                    "reference_id": {
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string",
                                      "enum": [
                                        "physical-goods",
                                        "digital-goods"
                                      ]
                                    },
                                    "payment_type": {
                                      "const": "br"
                                    },
                                    "payment_settings": {
                                      "type": "array",
                                      "minItems": 1,
                                      "maxItems": 1,
                                      "items": {
                                        "type": "object",
                                        "required": [
                                          "type",
                                          "pix_dynamic_code"
                                        ],
                                        "properties": {
                                          "type": {
                                            "const": "pix_dynamic_code"
                                          },
                                          "pix_dynamic_code": {
                                            "type": "object",
                                            "required": [
                                              "code",
                                              "merchant_name",
                                              "key",
                                              "key_type"
                                            ],
                                            "properties": {
                                              "code": {
                                                "type": "string"
                                              },
                                              "merchant_name": {
                                                "type": "string"
                                              },
                                              "key": {
                                                "type": "string"
                                              },
                                              "key_type": {
                                                "type": "string",
                                                "enum": [
                                                  "CPF",
                                                  "CNPJ",
                                                  "EMAIL",
                                                  "PHONE",
                                                  "EVP"
                                                ]
                                              }
                                            }
                                          }
                                        }
                                      }
                                    },
                                    "currency": {
                                      "const": "BRL"
                                    },
                                    "total_amount": {
                                      "$ref": "#/components/schemas/PaymentAmount"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageOrderDetails": {
        "description": "Pedido oficial com PIX dinâmico, link, boleto ou cartão habilitado. `order` é opcional; o cabeçalho de imagem só pode ser usado quando `order` estiver presente. Informe e persista uma `reference_id` própria desde a criação quando precisar confirmar ou atualizar a cobrança.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "order_details"
                  },
                  "header": {
                    "type": "object",
                    "required": [
                      "type",
                      "image"
                    ],
                    "properties": {
                      "type": {
                        "const": "image"
                      },
                      "image": {
                        "type": "object",
                        "required": [
                          "link"
                        ],
                        "properties": {
                          "link": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 1024
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "name",
                      "parameters"
                    ],
                    "properties": {
                      "name": {
                        "const": "review_and_pay"
                      },
                      "parameters": {
                        "type": "object",
                        "required": [
                          "reference_id",
                          "type",
                          "payment_type",
                          "payment_settings",
                          "currency",
                          "total_amount"
                        ],
                        "properties": {
                          "reference_id": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 60,
                            "pattern": "^[A-Za-z0-9_.-]+$",
                            "description": "Identificador único da cobrança, definido e persistido pela integração para atualizações futuras."
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "physical-goods",
                              "digital-goods"
                            ]
                          },
                          "payment_type": {
                            "const": "br"
                          },
                          "payment_settings": {
                            "type": "array",
                            "minItems": 1,
                            "items": {
                              "$ref": "#/components/schemas/PaymentSetting"
                            }
                          },
                          "currency": {
                            "const": "BRL"
                          },
                          "total_amount": {
                            "$ref": "#/components/schemas/PaymentAmount"
                          },
                          "order": {
                            "$ref": "#/components/schemas/PaymentOrder"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageOrderStatus": {
        "description": "Atualização enviada pela integração depois que o banco, gateway ou PSP informa o estado do pagamento; o WhatsApp não confirma a liquidação automaticamente. Use a mesma `reference_id` de um `order_details` já processado para que a Uno cite o pedido original e o aplicativo atualize seu estado. Aguarde o pedido original alcançar `sent` ou `delivered`.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MessageCommon"
          },
          {
            "type": "object",
            "required": [
              "interactive"
            ],
            "properties": {
              "type": {
                "const": "interactive"
              },
              "interactive": {
                "type": "object",
                "required": [
                  "type",
                  "body",
                  "action"
                ],
                "properties": {
                  "type": {
                    "const": "order_status"
                  },
                  "body": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  },
                  "footer": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "name",
                      "parameters"
                    ],
                    "properties": {
                      "name": {
                        "const": "review_order"
                      },
                      "parameters": {
                        "type": "object",
                        "required": [
                          "reference_id",
                          "payment"
                        ],
                        "properties": {
                          "reference_id": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 60,
                            "pattern": "^[A-Za-z0-9_.-]+$",
                            "description": "Mesma referência informada na criação da cobrança."
                          },
                          "order": {
                            "type": "object",
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "processing",
                                  "partially_shipped",
                                  "shipped",
                                  "completed",
                                  "canceled"
                                ]
                              },
                              "description": {
                                "type": "string"
                              }
                            }
                          },
                          "payment": {
                            "type": "object",
                            "required": [
                              "status"
                            ],
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "captured",
                                  "failed"
                                ]
                              },
                              "timestamp": {
                                "type": "integer",
                                "format": "int64",
                                "minimum": 0,
                                "description": "Horário real da confirmação pelo PSP em Unix segundos."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "MessageStatusUpdate": {
        "type": "object",
        "required": [
          "status",
          "message_id"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "read",
              "deleted"
            ],
            "description": "Marca a mensagem como lida ou apaga a mensagem enviada."
          },
          "message_id": {
            "type": "string",
            "minLength": 1,
            "description": "ID UnoAPI da mensagem alvo."
          }
        }
      },
      "MessageRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/MessageStatusBroadcast"
          },
          {
            "$ref": "#/components/schemas/MessageText"
          },
          {
            "$ref": "#/components/schemas/MessageLocation"
          },
          {
            "$ref": "#/components/schemas/MessageEdit"
          },
          {
            "$ref": "#/components/schemas/MessageImage"
          },
          {
            "$ref": "#/components/schemas/MessageVideo"
          },
          {
            "$ref": "#/components/schemas/MessageSticker"
          },
          {
            "$ref": "#/components/schemas/MessageAudio"
          },
          {
            "$ref": "#/components/schemas/MessageDocument"
          },
          {
            "$ref": "#/components/schemas/MessageContacts"
          },
          {
            "$ref": "#/components/schemas/MessageReaction"
          },
          {
            "$ref": "#/components/schemas/MessagePoll"
          },
          {
            "$ref": "#/components/schemas/MessagePollVote"
          },
          {
            "$ref": "#/components/schemas/MessageInteractiveButtons"
          },
          {
            "$ref": "#/components/schemas/MessageInteractiveCtaButtons"
          },
          {
            "$ref": "#/components/schemas/MessageInteractiveList"
          },
          {
            "$ref": "#/components/schemas/MessageInteractiveCarousel"
          },
          {
            "$ref": "#/components/schemas/MessagePaymentRequest"
          },
          {
            "$ref": "#/components/schemas/MessageOrderDetails"
          },
          {
            "$ref": "#/components/schemas/MessageOrderStatus"
          },
          {
            "$ref": "#/components/schemas/MessageStatusUpdate"
          }
        ]
      },
      "MessageResponse": {
        "type": "object",
        "required": [
          "messaging_product",
          "contacts",
          "messages"
        ],
        "properties": {
          "messaging_product": {
            "type": "string",
            "const": "whatsapp"
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "input",
                "wa_id"
              ],
              "properties": {
                "input": {
                  "type": "string",
                  "description": "Destinatário informado na requisição."
                },
                "wa_id": {
                  "type": "string"
                },
                "user_id": {
                  "type": "string",
                  "description": "Identificador interno do contato quando já resolvido."
                }
              }
            }
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "ID UnoAPI usado em edição, reação, voto, citação e acompanhamento."
                }
              }
            }
          },
          "status_skipped": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status_recipients": {
            "type": "integer"
          }
        }
      },
      "ContactsRequest": {
        "type": "object",
        "properties": {
          "blocking": {
            "type": "string",
            "example": "no_wait"
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "force_check": {
            "type": "boolean"
          }
        }
      },
      "ContactsResponse": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "wa_id": {
                  "type": "string"
                },
                "input": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ContactDirectoryResponse": {
        "type": "object",
        "required": [
          "contacts",
          "next_cursor",
          "has_more",
          "total_count"
        ],
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "user_id",
                "last_updated_ms"
              ],
              "properties": {
                "user_id": {
                  "type": "string",
                  "description": "LID canônico do contato"
                },
                "phone_number": {
                  "type": "string",
                  "description": "Telefone somente em dígitos; celulares brasileiros normalizados com o nono dígito"
                },
                "display_name": {
                  "type": "string"
                },
                "push_name": {
                  "type": "string"
                },
                "username": {
                  "type": "string",
                  "description": "Username opcional sincronizado pela Zapo"
                },
                "picture": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL legada quando já disponível no cache; a listagem não consulta o storage em caso de ausência"
                },
                "picture_id": {
                  "type": "string",
                  "description": "Identidade estável PN ou LID para download autenticado pela UnoAPI"
                },
                "last_updated_ms": {
                  "type": "integer",
                  "format": "int64"
                }
              }
            }
          },
          "next_cursor": {
            "type": "string"
          },
          "has_more": {
            "type": "boolean"
          },
          "total_count": {
            "type": "integer",
            "description": "Quantidade total de contatos armazenados no cache da sessão"
          }
        }
      },
      "ContactImportRequest": {
        "type": "object",
        "required": [
          "phone_number",
          "full_name"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "pattern": "^\\+?[0-9 ()-]{7,24}$",
            "description": "Número do contato. Não inclua sufixo JID.",
            "example": "5500000000002"
          },
          "full_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "example": "Contato Exemplo"
          },
          "first_name": {
            "type": "string",
            "maxLength": 128,
            "description": "Opcional; quando omitido, usa a primeira palavra de full_name.",
            "example": "Contato"
          },
          "user_id": {
            "type": "string",
            "pattern": "^[0-9]+@lid$",
            "description": "LID canônico opcional. Quando informado, prevalece para recuperar o PN exato no store Zapo.",
            "example": "123456789@lid"
          },
          "username": {
            "type": "string",
            "maxLength": 64,
            "description": "Username opcional, com ou sem @.",
            "example": "contato_exemplo"
          }
        }
      },
      "ContactImportResponse": {
        "type": "object",
        "required": [
          "success",
          "contact"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "contact": {
            "type": "object",
            "required": [
              "phone_number",
              "full_name",
              "first_name",
              "user_id"
            ],
            "properties": {
              "phone_number": {
                "type": "string",
                "description": "PN exato armazenado e usado pela Zapo, somente em dígitos."
              },
              "full_name": {
                "type": "string"
              },
              "first_name": {
                "type": "string"
              },
              "user_id": {
                "type": "string",
                "description": "LID canônico resolvido."
              },
              "username": {
                "type": "string"
              }
            }
          }
        }
      },
      "MediaResponse": {
        "type": "object",
        "properties": {
          "messaging_product": {
            "type": "string",
            "example": "whatsapp"
          },
          "mime_type": {
            "type": "string"
          },
          "sha256": {
            "type": "string"
          },
          "file_size": {
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "PreflightStatusRequest": {
        "type": "object",
        "properties": {
          "statusJidList": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "PreflightStatusResponse": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          },
          "session": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "online": {
                "type": "boolean"
              }
            }
          },
          "counts": {
            "type": "object",
            "properties": {
              "requested": {
                "type": "integer"
              },
              "normalized": {
                "type": "integer"
              },
              "valid": {
                "type": "integer"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "input": {
                  "type": "string"
                },
                "normalized": {
                  "type": "string"
                },
                "valid": {
                  "type": "boolean"
                },
                "wa_id": {
                  "type": "string"
                }
              }
            }
          },
          "ready": {
            "type": "boolean"
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "GroupsListResponse": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "jid": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "subject": {
                  "type": "string"
                },
                "picture": {
                  "type": "string",
                  "format": "uri"
                },
                "participantsCount": {
                  "type": "integer"
                },
                "participants_count": {
                  "type": "integer"
                }
              }
            }
          },
          "paging": {
            "type": "object",
            "properties": {
              "cursors": {
                "type": "object",
                "properties": {
                  "before": {
                    "type": "string",
                    "nullable": true
                  },
                  "after": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "GroupDetailsResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "jid": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "picture": {
            "type": "string"
          },
          "participants_count": {
            "type": "integer"
          },
          "total_participant_count": {
            "type": "integer"
          },
          "announcement": {
            "type": "boolean",
            "description": "true quando somente administradores podem enviar mensagens"
          },
          "locked": {
            "type": "boolean",
            "description": "true quando somente administradores podem editar as informações do grupo"
          },
          "join_approval_mode": {
            "type": "string",
            "enum": [
              "approval_required",
              "open"
            ]
          },
          "suspended": {
            "type": "boolean"
          },
          "creation_timestamp": {
            "type": "string"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "GroupSettingsRequest": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "announcement": {
            "type": "boolean",
            "description": "Define se somente administradores podem enviar mensagens"
          },
          "locked": {
            "type": "boolean",
            "description": "Define se somente administradores podem editar as informações do grupo"
          },
          "join_approval_mode": {
            "type": "string",
            "enum": [
              "approval_required",
              "open"
            ]
          }
        }
      },
      "GroupSettingsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GroupSettingsRequest"
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "updated": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "GroupParticipantsResponse": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string"
          },
          "group": {
            "type": "object",
            "properties": {
              "jid": {
                "type": "string"
              },
              "subject": {
                "type": "string"
              }
            }
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "jid": {
                  "type": "string",
                  "description": "Identificador do participante: PN em dígitos (sem @s.whatsapp.net) ou @lid"
                },
                "name": {
                  "type": "string",
                  "description": "Nome no cache de contatos quando disponível"
                }
              }
            }
          }
        }
      },
      "MessageWarning": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "example": "REPLY_SENT_WITHOUT_QUOTE",
            "description": "Código estável; um aviso não é uma falha e não exige reenvio. VIDEO_TRANSCODED informa conversão automática ao perfil solicitado (HD/SD); arquivo fora do recomendado ou metadados insuficientes."
          },
          "message": {
            "type": "string",
            "description": "Texto em pt-BR por padrão; UNOAPI_API_LANGUAGE=en seleciona inglês.",
            "example": "Mensagem enviada sem citação: não foi possível localizar a referência original nesta conversa."
          }
        }
      },
      "WebhookStatusFailed": {
        "description": "Payload de falha enviado ao webhook (fora da resposta HTTP)",
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "example": "whatsapp_business_account"
          },
          "entry": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "changes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "field": {
                        "type": "string",
                        "example": "messages"
                      },
                      "value": {
                        "type": "object",
                        "properties": {
                          "messaging_product": {
                            "type": "string",
                            "example": "whatsapp"
                          },
                          "metadata": {
                            "type": "object"
                          },
                          "statuses": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "recipient_id": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string",
                                  "example": "failed"
                                },
                                "timestamp": {
                                  "type": "integer"
                                },
                                "errors": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "code": {
                                        "type": "integer"
                                      },
                                      "title": {
                                        "type": "string"
                                      },
                                      "message": {
                                        "type": "string"
                                      },
                                      "error_data": {
                                        "type": "object",
                                        "description": "Diagnóstico normalizado do provider, sem stack trace"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "CatalogImage": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL servida pelo storage configurado na UnoAPI; não é a URL criptografada temporária do WhatsApp."
          },
          "mime_type": {
            "type": "string",
            "example": "image/jpeg"
          }
        }
      },
      "CatalogVariant": {
        "type": "object",
        "required": [
          "name",
          "value"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "Cor"
          },
          "value": {
            "type": "string",
            "example": "Preto"
          }
        }
      },
      "CatalogProduct": {
        "type": "object",
        "required": [
          "product_id",
          "title"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "example": "product_123"
          },
          "retailer_id": {
            "type": "string",
            "example": "sku_001"
          },
          "title": {
            "type": "string",
            "example": "Produto de demonstração"
          },
          "description": {
            "type": "string",
            "example": "Descrição fictícia do produto"
          },
          "currency": {
            "type": "string",
            "example": "BRL"
          },
          "price_amount_1000": {
            "type": "integer",
            "format": "int64",
            "description": "Preço multiplicado por 1000; 129900 representa BRL 129,90."
          },
          "sale_price_amount_1000": {
            "type": "integer",
            "format": "int64"
          },
          "formatted_price": {
            "type": "string",
            "example": "R$ 129,90"
          },
          "formatted_sale_price": {
            "type": "string",
            "example": "R$ 119,90"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "image": {
            "$ref": "#/components/schemas/CatalogImage"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CatalogVariant"
            }
          },
          "business_owner_id": {
            "type": "string",
            "description": "JID/LID do proprietário comercial informado pelo WhatsApp."
          },
          "body": {
            "type": "string"
          },
          "footer": {
            "type": "string"
          }
        }
      },
      "CatalogOrderItem": {
        "type": "object",
        "required": [
          "product_id",
          "title",
          "quantity"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "example": "product_123"
          },
          "retailer_id": {
            "type": "string",
            "example": "sku_001"
          },
          "title": {
            "type": "string",
            "example": "Produto de demonstração"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          },
          "currency": {
            "type": "string",
            "example": "BRL"
          },
          "unit_price_amount_1000": {
            "type": "integer",
            "format": "int64"
          },
          "subtotal_amount_1000": {
            "type": "integer",
            "format": "int64"
          },
          "formatted_unit_price": {
            "type": "string",
            "example": "R$ 129,90"
          },
          "formatted_subtotal": {
            "type": "string",
            "example": "R$ 259,80"
          },
          "image": {
            "$ref": "#/components/schemas/CatalogImage"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CatalogVariant"
            }
          }
        }
      },
      "CatalogOrder": {
        "type": "object",
        "required": [
          "order_id",
          "status",
          "resolution_status",
          "item_count",
          "items"
        ],
        "properties": {
          "order_id": {
            "type": "string",
            "example": "order_123"
          },
          "title": {
            "type": "string",
            "example": "Pedido de demonstração"
          },
          "status": {
            "type": "string",
            "enum": [
              "inquiry",
              "accepted",
              "declined",
              "unknown"
            ]
          },
          "catalog_type": {
            "type": "string",
            "example": "NATIVE"
          },
          "resolution_status": {
            "type": "string",
            "enum": [
              "resolved",
              "summary",
              "failed"
            ],
            "description": "resolved contém os itens consultados; summary preserva somente o resumo recebido; failed indica falha na consulta sem perder a mensagem."
          },
          "currency": {
            "type": "string",
            "example": "BRL"
          },
          "item_count": {
            "type": "integer",
            "minimum": 0
          },
          "subtotal_amount_1000": {
            "type": "integer",
            "format": "int64"
          },
          "total_amount_1000": {
            "type": "integer",
            "format": "int64"
          },
          "formatted_subtotal": {
            "type": "string",
            "example": "R$ 259,80"
          },
          "formatted_total": {
            "type": "string",
            "example": "R$ 259,80"
          },
          "message": {
            "type": "string"
          },
          "image": {
            "$ref": "#/components/schemas/CatalogImage"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CatalogOrderItem"
            }
          }
        }
      },
      "WebhookInbound": {
        "description": "Mensagens recebidas no envelope API ViperConnect, com extensões ViperConnect como message_type=view_once.",
        "type": "object",
        "properties": {
          "object": {
            "type": "string"
          },
          "entry": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "changes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "field": {
                        "type": "string",
                        "example": "messages"
                      },
                      "value": {
                        "type": "object",
                        "properties": {
                          "messaging_product": {
                            "type": "string",
                            "example": "whatsapp"
                          },
                          "metadata": {
                            "type": "object"
                          },
                          "contacts": {
                            "type": "array",
                            "items": {
                              "type": "object"
                            }
                          },
                          "messages": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "timestamp": {
                                  "type": "string"
                                },
                                "message_type": {
                                  "type": "string",
                                  "example": "view_once",
                                  "description": "Extensão ViperConnect. view_once identifica imagem, vídeo ou áudio de visualização única no evento original, sem novo ID ou evento posterior. message_edit identifica edição. Ausente em mídia comum; não impõe acesso único à URL."
                                },
                                "type": {
                                  "type": "string",
                                  "description": "Inclui os tipos estruturados `product` e `order` para eventos de catálogo."
                                },
                                "fallback_text": {
                                  "type": "string",
                                  "description": "Texto seguro para clientes que ainda não renderizam o componente estruturado."
                                },
                                "product": {
                                  "$ref": "#/components/schemas/CatalogProduct"
                                },
                                "order": {
                                  "$ref": "#/components/schemas/CatalogOrder"
                                },
                                "interactive": {
                                  "type": "object",
                                  "description": "Resposta de botão ou lista interativa.",
                                  "properties": {
                                    "type": {
                                      "type": "string",
                                      "enum": [
                                        "button_reply",
                                        "list_reply"
                                      ]
                                    },
                                    "list_reply": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "description": "Mesmo valor enviado originalmente em `rows[].id`."
                                        },
                                        "title": {
                                          "type": "string"
                                        },
                                        "description": {
                                          "type": "string"
                                        }
                                      }
                                    },
                                    "button_reply": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string"
                                        },
                                        "title": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "example": {
          "object": "whatsapp_business_account",
          "entry": [
            {
              "id": "5511999999999",
              "changes": [
                {
                  "field": "messages",
                  "value": {
                    "messaging_product": "whatsapp",
                    "messages": [
                      {
                        "from": "5566999999999",
                        "id": "MESSAGE_ID",
                        "timestamp": "1784900000",
                        "type": "interactive",
                        "interactive": {
                          "type": "list_reply",
                          "list_reply": {
                            "id": "plan_basic",
                            "title": "Básico",
                            "description": "R$ 10"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      },
      "WebhookAck": {
        "description": "Status de mensagens enviadas (sent/delivered/read/deleted). Avisos opcionais devem ser mesclados por ID e código, mesmo em status já processados.",
        "type": "object",
        "properties": {
          "object": {
            "type": "string"
          },
          "entry": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "changes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "field": {
                        "type": "string",
                        "example": "messages"
                      },
                      "value": {
                        "type": "object",
                        "properties": {
                          "messaging_product": {
                            "type": "string"
                          },
                          "statuses": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "recipient_id": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string",
                                  "example": "delivered"
                                },
                                "timestamp": {
                                  "type": "integer"
                                },
                                "warnings": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/MessageWarning"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Administração",
      "description": "Infraestrutura global: acesso administrativo obrigatório. Escritas e exclusões alteram dados reais; executar somente após revisão."
    },
    {
      "name": "Manager",
      "description": "Usuários, atribuições persistentes e chaves pessoais; recurso local, não implantado."
    },
    {
      "name": "Sistema",
      "description": "Disponibilidade e versão da API."
    },
    {
      "name": "Sessões",
      "description": "Cadastro, estado e gerenciamento das sessões."
    },
    {
      "name": "Pareamento",
      "description": "QR code, código numérico e desafios de pareamento."
    },
    {
      "name": "Mensagens",
      "description": "Envio, recuperação, pré-validação e timers."
    },
    {
      "name": "Contatos",
      "description": "Diretório de contatos armazenado pela sessão."
    },
    {
      "name": "Perfil",
      "description": "Consulta e edição da própria conta WhatsApp; campos comerciais exigem Business."
    },
    {
      "name": "Grupos",
      "description": "Grupos, participantes, administradores, convites e solicitações."
    },
    {
      "name": "Mídia",
      "description": "Consulta e download de arquivos de mídia."
    },
    {
      "name": "Modelos de mensagem",
      "description": "Consulta e gerenciamento de modelos de mensagem."
    },
    {
      "name": "Webhooks",
      "description": "Recebimento, validação e configuração de webhooks."
    },
    {
      "name": "Diagnóstico",
      "description": "Ressincronização e inspeção operacional da sessão."
    },
    {
      "name": "Telefonia",
      "description": "Bridge Zapo, chamadas, ramais e operação SIP/WebRTC/RTP."
    }
  ]
}
