{
  "openapi": "3.1.0",
  "info": {
    "title": "APIFacil WhatsApp API v2",
    "description": "API v2 do WhatsApp. Autenticacao via header Authorization (sem Bearer). Todas as rotas usam middleware auth.api (Sanctum) com rate limiting.",
    "version": "2.0.0",
    "contact": {
      "name": "APIFacil",
      "url": "https://apifacil.com"
    }
  },
  "servers": [
    {
      "url": "https://apifacil.dev/api/v2",
      "description": "Producao"
    },
    {
      "url": "http://localhost:8001/api/v2",
      "description": "Local"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Token de API direto (sem prefixo Bearer)"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Token invalido ou ausente",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Nao autorizado", "data": null } } }
      },
      "Forbidden": {
        "description": "Limite do plano excedido ou recurso indisponivel",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Limite de instancias do plano atingido", "data": null } } }
      },
      "NotFound": {
        "description": "Recurso nao encontrado",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Instancia nao encontrada", "data": null } } }
      },
      "ValidationError": {
        "description": "Erro de validacao de dados",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "O destino (to) e obrigatorio.", "data": null } } }
      },
      "ServerError": {
        "description": "Erro interno do servidor",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Erro ao comunicar com microservico", "data": null } } }
      },
      "RateLimit": {
        "description": "Limite de requisicoes excedido",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Muitas requisicoes. Tente novamente em alguns segundos.", "data": null } } }
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": { "type": "boolean", "example": true },
          "message": { "type": "string" },
          "data": { "type": "object", "nullable": true }
        },
        "required": ["error", "message"]
      },
      "InstanciaV2": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "nome": { "type": "string", "example": "WhatsApp Comercial" },
          "codigo": { "type": "string", "format": "uuid", "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" },
          "session_id": { "type": "string", "example": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890" },
          "phone_number": { "type": "string", "nullable": true, "example": "5511999999999" },
          "status": {
            "type": "string",
            "enum": ["disconnected", "connecting", "connected", "qr_code", "pairing", "sleep", "inactive"],
            "example": "disconnected"
          },
          "metadata": { "type": "object", "nullable": true },
          "last_connected_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time", "example": "2026-07-24T12:00:00.000000Z" },
          "updated_at": { "type": "string", "format": "date-time", "example": "2026-07-24T12:00:00.000000Z" },
          "configuracao": { "$ref": "#/components/schemas/ConfiguracaoV2", "nullable": true },
          "fila": { "$ref": "#/components/schemas/FilaV2", "nullable": true },
          "servidor": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": { "type": "string" },
              "nome": { "type": "string", "nullable": true },
              "ip": { "type": "string" },
              "quantidade_maxima": { "type": "integer" }
            }
          }
        }
      },
      "ConfiguracaoV2": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "instancia_id": { "type": "integer", "example": 1 },
          "webhook_url": { "type": "string", "format": "uri", "nullable": true, "example": "https://meusite.com/webhook" },
          "webhook_ativo": { "type": "boolean", "example": false },
          "webhook_grupo": { "type": "string", "format": "uri", "nullable": true, "example": "https://meusite.com/webhook-grupo" },
          "config_json": { "type": "object", "example": { "tipos_envio": ["text", "image"] }, "description": "Configuracoes adicionais. tipos_envio: lista de tipos que NAO disparam webhook (text, image, video, audio, document, sticker, location, etc)." }
        }
      },
      "FilaV2": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "instancia_id": { "type": "integer", "example": 1 },
          "nome": { "type": "string", "example": "Instancia 1" },
          "queue_name": { "type": "string", "example": "apifacil:whatsapp_v2:queue:instance:1" },
          "tipo": { "type": "string", "enum": ["instancia", "usuario", "plano", "global"], "example": "instancia" },
          "concorrencia": { "type": "integer", "example": 1 },
          "delay_min_ms": { "type": "integer", "example": 1000 },
          "delay_max_ms": { "type": "integer", "example": 3000 },
          "schedule_enabled": { "type": "boolean", "example": false },
          "schedule_start_hour": { "type": "integer", "example": 8 },
          "schedule_end_hour": { "type": "integer", "example": 22 },
          "ativo": { "type": "boolean", "example": true }
        }
      },
      "MensagemV2": {
        "type": "object",
        "description": "Mensagem v2. Webhook events: message_sent, message_received, message_status (delivered/read/played), message_error. Campos quoted_message_id e quoted_participant presentes em replies.",
        "properties": {
          "id": { "type": "integer", "example": 123 },
          "instancia_id": { "type": "integer", "example": 1 },
          "user_id": { "type": "integer", "example": 1 },
          "message_id": { "type": "string", "nullable": true, "example": "3EB0123456789ABCDEF" },
          "remote_jid": { "type": "string", "nullable": true, "example": "5511999999999@s.whatsapp.net" },
          "remote_jid_alt": { "type": "string", "nullable": true },
          "from_me": { "type": "boolean", "example": true },
          "participant": { "type": "string", "nullable": true },
          "tipo": {
            "type": "string",
            "enum": ["text", "image", "video", "audio", "document", "sticker", "location", "contact", "button", "poll", "unknown"],
            "example": "text"
          },
          "conteudo": { "type": "string", "nullable": true, "example": "Ola, como vai?" },
          "caption": { "type": "string", "nullable": true },
          "media_url": { "type": "string", "nullable": true, "example": "https://exemplo.com/imagem.jpg" },
          "media_mimetype": { "type": "string", "nullable": true, "example": "image/jpeg" },
          "file_name": { "type": "string", "nullable": true },
          "respondido": { "type": "boolean", "description": "true se esta mensagem foi respondida (reply)", "example": false },
          "quoted_message_id": { "type": "string", "nullable": true, "description": "ID da mensagem original (se esta for uma reply)", "example": "3EB0123456789ABCDEF" },
          "quoted_participant": { "type": "string", "nullable": true, "description": "Participante da mensagem original (em grupos)", "example": "5511999999999@s.whatsapp.net" },
          "latitude": { "type": "number", "nullable": true, "example": -23.5613 },
          "longitude": { "type": "number", "nullable": true, "example": -46.6565 },
          "push_name": { "type": "string", "nullable": true, "example": "Joao Silva" },
          "status": {
            "type": "string",
            "enum": ["pending", "sent", "delivered", "read", "played", "failed"],
            "example": "sent"
          },
          "erro": { "type": "boolean", "example": false },
          "erro_mensagem": { "type": "string", "nullable": true },
          "origem": {
            "type": "string",
            "enum": ["api", "direto", "workflow"],
            "example": "api"
          },
          "webhook_status": {
            "type": "string",
            "enum": ["pending", "sent", "failed", "skipped"],
            "example": "pending"
          },
          "webhook_tentativas": { "type": "integer", "example": 0 },
          "webhook_proxima_tentativa": { "type": "string", "format": "date-time", "nullable": true },
          "timestamp_whatsapp": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time", "example": "2026-07-24T12:00:00.000000Z" },
          "updated_at": { "type": "string", "format": "date-time", "example": "2026-07-24T12:00:00.000000Z" }
        }
      },
      "SendMessageRequest": {
        "type": "object",
        "required": ["to", "type"],
        "properties": {
          "to": {
            "type": "string",
            "description": "Numero de telefone (DDI+DDD+numero, apenas digitos) ou JID do destino",
            "example": "5511999999999"
          },
          "type": {
            "type": "string",
            "enum": ["text", "image", "video", "audio", "document", "location"],
            "example": "text"
          },
          "content": {
            "type": "string",
            "description": "Conteudo da mensagem (obrigatorio para type=text)",
            "example": "Ola, como vai?"
          },
          "mediaUrl": {
            "type": "string",
            "format": "uri",
            "description": "URL publica da midia (alternativa a mediaBase64). Obrigatorio para image, video, audio, document se mediaBase64 nao for enviado. Deve ser acessivel publicamente (nao use localhost).",
            "example": "https://exemplo.com/imagem.jpg"
          },
          "mediaBase64": {
            "type": "string",
            "description": "Midia em base64 (alternativa a mediaUrl). Aceita prefixo data:image/...;base64, ou base64 puro. Obrigatorio para image, video, audio, document se mediaUrl nao for enviado.",
            "example": "iVBORw0KGgoAAAANSUhEUgAA..."
          },
          "caption": {
            "type": "string",
            "description": "Legenda da midia (opcional para image, video, document)",
            "example": "Foto do produto"
          },
          "fileName": {
            "type": "string",
            "description": "Nome do arquivo (opcional para document)",
            "example": "contrato.pdf"
          },
          "latitude": {
            "type": "number",
            "description": "Latitude (obrigatorio para type=location)",
            "example": -23.5613
          },
          "longitude": {
            "type": "number",
            "description": "Longitude (obrigatorio para type=location)",
            "example": -46.6565
          },
          "locationName": {
            "type": "string",
            "description": "Nome do local (opcional para location)",
            "example": "Escritorio"
          },
          "address": {
            "type": "string",
            "description": "Endereco do local (opcional para location)",
            "example": "Av. Paulista, 1000"
          },
          "enqueue": {
            "type": "boolean",
            "default": true,
            "description": "Se true, enfileira a mensagem com delay aleatorio configuravel. Se false, envia imediatamente."
          }
        }
      },
      "CreateInstanciaRequest": {
        "type": "object",
        "required": ["nome"],
        "properties": {
          "nome": { "type": "string", "example": "WhatsApp Comercial" },
          "servidor_id": { "type": "string", "nullable": true, "description": "UUID do servidor (opcional, atribuido automaticamente se vazio)" }
        }
      },
      "UpdateConfiguracaoRequest": {
        "type": "object",
        "properties": {
          "webhook_url": { "type": "string", "format": "uri", "nullable": true, "example": "https://meusite.com/webhook" },
          "webhook_ativo": { "type": "boolean", "example": true },
          "webhook_grupo": { "type": "string", "format": "uri", "nullable": true, "example": "https://meusite.com/webhook-grupo" },
          "config_json": { "type": "object", "example": { "tipos_envio": ["text", "image"] } }
        }
      },
      "PairingRequest": {
        "type": "object",
        "required": ["phone"],
        "properties": {
          "phone": {
            "type": "string",
            "description": "Numero de telefone com DDI e DDD (apenas digitos, 10 a 15)",
            "example": "5511999999999"
          }
        }
      },
      "CheckWhatsappRequest": {
        "type": "object",
        "required": ["phone"],
        "properties": {
          "phone": { "type": "string", "description": "Numero de telefone com DDI e DDD", "example": "5511999999999" }
        }
      },
      "StatusInstancia": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "status_banco": { "type": "string", "example": "connected" },
          "status_microservico": { "type": "string", "nullable": true, "example": "connected" },
          "qr_code": { "type": "string", "nullable": true, "description": "QR Code em base64 (quando aplicavel)" },
          "pairing_code": { "type": "string", "nullable": true, "example": "W4NQJMRD" },
          "reconnect_attempts": { "type": "integer", "example": 0 },
          "last_connected_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "SendMensagemResponse": {
        "type": "object",
        "properties": {
          "messageId": { "type": "string", "nullable": true, "description": "ID da mensagem no WhatsApp (apenas para envio direto, null quando enfileirado)", "example": "3EB0123456789ABCDEF" },
          "status": { "type": "string", "nullable": true, "description": "Status da mensagem (apenas para envio direto)", "example": "sent" },
          "queued": { "type": "boolean", "description": "true = mensagem foi enfileirada, false = enviada diretamente", "example": true }
        }
      }
    }
  },
  "security": [{ "ApiKeyAuth": [] }],
  "tags": [
    { "name": "Instancias", "description": "Criar, listar, gerenciar e deletar instancias WhatsApp v2" },
    { "name": "Conexao", "description": "Conectar instancias via QR Code, Pairing Code ou Importar Sessao" },
    { "name": "Mensagens", "description": "Enviar mensagens e consultar historico" },
    { "name": "Configuracoes", "description": "Configurar webhooks e comportamento da instancia" },
    { "name": "Utilitarios", "description": "Verificar numeros e obter fotos de perfil" }
  ],
  "paths": {
    "/whatsapp/instancia/criar": {
      "post": {
        "tags": ["Instancias"],
        "summary": "Criar nova instancia",
        "description": "Cria uma nova instancia WhatsApp v2 com configuracao e fila padrao. Atribui servidor automaticamente se servidor_id for vazio.",
        "operationId": "criarInstanciaV2",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateInstanciaRequest" },
              "example": { "nome": "WhatsApp Comercial" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Instancia criada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Instancia criada com sucesso" },
                    "data": { "$ref": "#/components/schemas/InstanciaV2" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Instancia criada com sucesso",
                  "data": {
                    "id": 1,
                    "nome": "WhatsApp Comercial",
                    "codigo": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "session_id": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "phone_number": null,
                    "status": "disconnected",
                    "metadata": null,
                    "last_connected_at": null,
                    "created_at": "2026-07-24T12:00:00.000000Z",
                    "updated_at": "2026-07-24T12:00:00.000000Z",
                    "configuracao": {
                      "id": 1,
                      "instancia_id": 1,
                      "webhook_url": null,
                      "webhook_ativo": false,
                      "webhook_grupo": null,
                      "config_json": []
                    },
                    "fila": {
                      "id": 1,
                      "instancia_id": 1,
                      "nome": "Instancia 1",
                      "queue_name": "apifacil:whatsapp_v2:queue:instance:1",
                      "tipo": "instancia",
                      "concorrencia": 1,
                      "delay_min_ms": 1000,
                      "delay_max_ms": 3000,
                      "schedule_enabled": false,
                      "schedule_start_hour": 8,
                      "schedule_end_hour": 22,
                      "ativo": true
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimit" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/whatsapp/instancia/listar": {
      "get": {
        "tags": ["Instancias"],
        "summary": "Listar instancias",
        "description": "Lista todas as instancias v2 do usuario autenticado com configuracao, fila e servidor.",
        "operationId": "listarInstanciasV2",
        "responses": {
          "200": {
            "description": "Lista de instancias",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Instancias listadas" },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/InstanciaV2" }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Instancias listadas",
                  "data": [
                    {
                      "id": 1,
                      "nome": "WhatsApp Comercial",
                      "codigo": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "session_id": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "phone_number": "5511999999999",
                      "status": "connected",
                      "last_connected_at": "2026-07-24T12:00:00.000000Z",
                      "created_at": "2026-07-24T11:00:00.000000Z",
                      "updated_at": "2026-07-24T12:00:00.000000Z",
                      "configuracao": { "id": 1, "instancia_id": 1, "webhook_url": "https://meusite.com/webhook", "webhook_ativo": true, "webhook_grupo": null, "config_json": {} },
                      "fila": { "id": 1, "instancia_id": 1, "nome": "Instancia 1", "queue_name": "apifacil:whatsapp_v2:queue:instance:1", "tipo": "instancia", "concorrencia": 1, "delay_min_ms": 1000, "delay_max_ms": 3000, "schedule_enabled": false, "schedule_start_hour": 8, "schedule_end_hour": 22, "ativo": true },
                      "servidor": { "id": "cac1e11f-f541-4bab-953f-ad27cac03a95", "nome": "Servidor Local", "ip": "127.0.0.1", "quantidade_maxima": 100 }
                    }
                  ]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/detalhes": {
      "get": {
        "tags": ["Instancias"],
        "summary": "Detalhes da instancia",
        "description": "Retorna dados completos da instancia incluindo configuracao, fila e servidor. Aceita ID numerico ou codigo UUID.",
        "operationId": "detalhesInstanciaV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID numerico ou codigo UUID da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Detalhes da instancia",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Detalhes da instancia" },
                    "data": { "$ref": "#/components/schemas/InstanciaV2" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Detalhes da instancia",
                  "data": {
                    "id": 1,
                    "nome": "WhatsApp Comercial",
                    "codigo": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "session_id": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                    "phone_number": "5511999999999",
                    "status": "connected",
                    "configuracao": { "id": 1, "instancia_id": 1, "webhook_url": "https://meusite.com/webhook", "webhook_ativo": true, "webhook_grupo": null, "config_json": {} },
                    "fila": { "id": 1, "instancia_id": 1, "nome": "Instancia 1", "queue_name": "apifacil:whatsapp_v2:queue:instance:1", "tipo": "instancia", "concorrencia": 1, "delay_min_ms": 1000, "delay_max_ms": 3000, "schedule_enabled": false, "schedule_start_hour": 8, "schedule_end_hour": 22, "ativo": true },
                    "servidor": { "id": "cac1e11f-f541-4bab-953f-ad27cac03a95", "nome": "Servidor Local", "ip": "127.0.0.1", "quantidade_maxima": 100 }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/status": {
      "get": {
        "tags": ["Instancias"],
        "summary": "Obter status da instancia",
        "description": "Retorna o status atual da instancia combinando dados do banco e do microservico. Inclui QR Code e pairing code se disponiveis.",
        "operationId": "statusInstanciaV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Status da instancia",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Status da instancia" },
                    "data": { "$ref": "#/components/schemas/StatusInstancia" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Status da instancia",
                  "data": {
                    "id": 1,
                    "status_banco": "connected",
                    "status_microservico": "connected",
                    "qr_code": null,
                    "pairing_code": null,
                    "reconnect_attempts": 0,
                    "last_connected_at": "2026-07-24T12:00:00.000000Z"
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/qrcode": {
      "get": {
        "tags": ["Conexao"],
        "summary": "Obter QR Code",
        "description": "Retorna o QR Code atual em base64 para pareamento. E necessario chamar /iniciar primeiro para gerar o QR Code.",
        "operationId": "qrcodeV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "QR Code disponivel",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "QR Code" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "qr_code": { "type": "string", "example": "2@/AW1mZXNhc3dhcmUuY29t..." }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "QR Code",
                  "data": { "qr_code": "2@/AW1mZXNhc3dhcmUuY29t..." }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "QR Code nao disponivel",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "QR Code nao disponivel. Inicie a sessao primeiro.", "data": null } } }
          },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/iniciar": {
      "post": {
        "tags": ["Conexao"],
        "summary": "Iniciar sessao",
        "description": "Inicia a sessao WhatsApp no microservico. Gera QR Code se necessario. O status da instancia muda para 'connecting'.",
        "operationId": "iniciarSessaoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Sessao iniciada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Sessao iniciada" },
                    "data": { "type": "object", "nullable": true }
                  }
                },
                "example": { "error": false, "message": "Sessao iniciada", "data": { "sessionId": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "connecting", "qrCode": null } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/importar-sessao": {
      "post": {
        "tags": ["Conexao"],
        "summary": "Importar sessao existente",
        "description": "Importa uma sessao previamente pareada do armazenamento PostgreSQL do microservico. A sessao conecta automaticamente apos a importacao.",
        "operationId": "importarSessaoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Sessao importada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Sessao importada" },
                    "data": { "type": "object", "nullable": true }
                  }
                },
                "example": { "error": false, "message": "Sessao importada e iniciada", "data": { "status": "connected" } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/solicitar-pareamento": {
      "post": {
        "tags": ["Conexao"],
        "summary": "Solicitar codigo de pareamento",
        "description": "Inicia a sessao automaticamente e solicita um codigo de pareamento para conectar via telefone (alternativa ao QR Code). O codigo expira em 120 segundos. O usuario deve digitar o codigo no WhatsApp do celular: Configuracoes -> Aparelhos conectados -> Conectar com codigo.",
        "operationId": "solicitarPareamentoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PairingRequest" },
              "example": { "phone": "5511999999999" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Codigo de pareamento gerado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Codigo de pareamento gerado" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "pairingCode": { "type": "string", "example": "W4NQJMRD" },
                        "formattedCode": { "type": "string", "nullable": true, "example": "W4NQ-JMRD" }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Codigo de pareamento gerado",
                  "data": { "pairingCode": "W4NQJMRD", "formattedCode": "W4NQ-JMRD" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/codigo-pareamento": {
      "get": {
        "tags": ["Conexao"],
        "summary": "Obter codigo de pareamento atual",
        "description": "Recupera o codigo de pareamento atual do microservico. Retorna 404 se nao houver codigo disponivel.",
        "operationId": "codigoPareamentoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Codigo de pareamento",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Codigo de pareamento" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "pairing_code": { "type": "string", "example": "W4NQJMRD" }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Codigo de pareamento",
                  "data": { "pairing_code": "W4NQJMRD" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "Codigo nao disponivel",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Codigo de pareamento nao disponivel.", "data": null } } }
          },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/pausar": {
      "post": {
        "tags": ["Conexao"],
        "summary": "Pausar sessao",
        "description": "Desconecta a sessao no microservico sem remover credenciais. A instancia pode ser reativada com /iniciar.",
        "operationId": "pausarSessaoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Sessao pausada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Sessao fechada" },
                    "data": { "type": "object", "nullable": true }
                  }
                },
                "example": { "error": false, "message": "Sessao fechada", "data": null }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/desconectar": {
      "post": {
        "tags": ["Conexao"],
        "summary": "Desconectar e remover credenciais",
        "description": "Faz logout completo no microservico. A instancia precisara ser re-pareada (QR Code ou pairing code).",
        "operationId": "desconectarInstanciaV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Sessao desconectada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Sessao fechada" },
                    "data": { "type": "object", "nullable": true }
                  }
                },
                "example": { "error": false, "message": "Sessao fechada", "data": { "sessionId": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890" } }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}": {
      "delete": {
        "tags": ["Instancias"],
        "summary": "Deletar instancia",
        "description": "Remove a instancia, configuracao, fila e todas as mensagens. Irreversivel.",
        "operationId": "deletarInstanciaV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "responses": {
          "200": {
            "description": "Instancia deletada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Instancia deletada" },
                    "data": { "type": "object", "nullable": true }
                  }
                },
                "example": { "error": false, "message": "Instancia deletada", "data": null }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/configuracao": {
      "put": {
        "tags": ["Configuracoes"],
        "summary": "Atualizar configuracao",
        "description": "Atualiza webhook e configuracoes da instancia.",
        "operationId": "atualizarConfiguracaoV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/UpdateConfiguracaoRequest" },
              "example": {
                "webhook_url": "https://meusite.com/webhook",
                "webhook_ativo": true,
                "webhook_grupo": "https://meusite.com/webhook-grupo",
                "config_json": { "tipos_envio": ["text", "image"] }
              },
              "description": "webhook_url: URL para mensagens privadas. webhook_grupo: URL para grupos. webhook_ativo: master switch. config_json.tipos_envio: tipos que NAO disparam webhook."
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuracao atualizada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Configuracao atualizada" },
                    "data": { "$ref": "#/components/schemas/ConfiguracaoV2" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Configuracao atualizada",
                  "data": {
                    "id": 1,
                    "instancia_id": 1,
                    "webhook_url": "https://meusite.com/webhook",
                    "webhook_ativo": true,
                    "webhook_grupo": "https://meusite.com/webhook-grupo",
                    "config_json": { "tipos_envio": ["text", "image"] }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/verificar-numero": {
      "post": {
        "tags": ["Utilitarios"],
        "summary": "Verificar se numero existe no WhatsApp",
        "description": "Consulta se um numero de telefone possui conta WhatsApp ativa. A instancia deve estar conectada.",
        "operationId": "verificarNumeroV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CheckWhatsappRequest" },
              "example": { "phone": "5511999999999" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resultado da verificacao",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Numero existe no WhatsApp" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "exists": { "type": "boolean", "example": true },
                        "phone": { "type": "string", "example": "5511999999999" }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Numero existe no WhatsApp",
                  "data": { "exists": true, "phone": "5511999999999" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/foto-perfil": {
      "post": {
        "tags": ["Utilitarios"],
        "summary": "Obter foto de perfil",
        "description": "Consulta a foto de perfil de um numero. A instancia deve estar conectada.",
        "operationId": "fotoPerfilV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CheckWhatsappRequest" },
              "example": { "phone": "5511999999999" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Foto de perfil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Foto encontrada" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": { "type": "string", "nullable": true, "example": "https://pps.whatsapp.net/v/t61.12345..." },
                        "phone": { "type": "string", "example": "5511999999999" }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Foto encontrada",
                  "data": { "url": "https://pps.whatsapp.net/v/t61.12345...", "phone": "5511999999999" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "500": { "$ref": "#/components/responses/ServerError" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/mensagens": {
      "get": {
        "tags": ["Mensagens"],
        "summary": "Listar mensagens da instancia",
        "description": "Lista mensagens da instancia com paginacao. Filtros opcionais por data e tipo.",
        "operationId": "listarMensagensV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" },
          { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15, "maximum": 100 }, "description": "Itens por pagina (max 100)" },
          { "name": "data_inicial", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Data inicial (YYYY-MM-DD)" },
          { "name": "data_final", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Data final (YYYY-MM-DD)" },
          { "name": "tipo", "in": "query", "schema": { "type": "string" }, "description": "Filtrar por tipo (text, image, video, audio, document, etc)" }
        ],
        "responses": {
          "200": {
            "description": "Mensagens paginadas",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Mensagens listadas" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "current_page": { "type": "integer", "example": 1 },
                        "data": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/MensagemV2" }
                        },
                        "total": { "type": "integer", "example": 50 },
                        "per_page": { "type": "integer", "example": 15 },
                        "last_page": { "type": "integer", "example": 4 },
                        "from": { "type": "integer", "example": 1 },
                        "to": { "type": "integer", "example": 15 }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Mensagens listadas",
                  "data": {
                    "current_page": 1,
                    "data": [
                      {
                        "id": 123,
                        "instancia_id": 1,
                        "user_id": 1,
                        "message_id": "3EB0123456789ABCDEF",
                        "remote_jid": "5511999999999@s.whatsapp.net",
                        "from_me": true,
                        "tipo": "text",
                        "conteudo": "Ola, como vai?",
                        "status": "sent",
                        "origem": "api",
                        "webhook_status": "pending",
                        "created_at": "2026-07-24T12:00:00.000000Z",
                        "updated_at": "2026-07-24T12:00:00.000000Z"
                      }
                    ],
                    "total": 50,
                    "per_page": 15,
                    "last_page": 4,
                    "from": 1,
                    "to": 15
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/instancia/{id}/mensagens/{mensagemId}": {
      "get": {
        "tags": ["Mensagens"],
        "summary": "Consultar mensagem especifica",
        "description": "Retorna os detalhes de uma mensagem especifica incluindo logs de webhook.",
        "operationId": "consultarMensagemV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID ou codigo da instancia" },
          { "name": "mensagemId", "in": "path", "required": true, "schema": { "type": "integer" }, "description": "ID da mensagem" }
        ],
        "responses": {
          "200": {
            "description": "Detalhes da mensagem",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Detalhes da mensagem" },
                    "data": { "$ref": "#/components/schemas/MensagemV2" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Detalhes da mensagem",
                  "data": {
                    "id": 123,
                    "instancia_id": 1,
                    "user_id": 1,
                    "message_id": "3EB0123456789ABCDEF",
                    "remote_jid": "5511999999999@s.whatsapp.net",
                    "from_me": true,
                    "tipo": "text",
                    "conteudo": "Ola, como vai?",
                    "status": "delivered",
                    "origem": "api",
                    "webhook_status": "sent",
                    "webhook_tentativas": 1,
                    "created_at": "2026-07-24T12:00:00.000000Z",
                    "updated_at": "2026-07-24T12:01:00.000000Z"
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimit" }
        }
      }
    },
    "/whatsapp/mensagem/{id}/enviar": {
      "post": {
        "tags": ["Mensagens"],
        "summary": "Enviar mensagem",
        "description": "Envia uma mensagem via WhatsApp. Por padrao (enqueue=true) enfileira a mensagem com delay aleatorio configuravel e retorna 202. Use enqueue=false para envio imediato (retorna 200). A instancia deve estar conectada.",
        "operationId": "enviarMensagemV2",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "ID numerico ou codigo UUID da instancia" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendMessageRequest" },
              "examples": {
                "Texto": {
                  "summary": "Mensagem de texto",
                  "value": { "to": "5511999999999", "type": "text", "content": "Ola, como vai?" }
                },
                "Imagem": {
                  "summary": "Imagem via URL publica",
                  "value": { "to": "5511999999999", "type": "image", "mediaUrl": "https://exemplo.com/imagem.jpg", "caption": "Foto do produto" }
                },
                "ImagemBase64": {
                  "summary": "Imagem via base64",
                  "value": { "to": "5511999999999", "type": "image", "mediaBase64": "iVBORw0KGgoAAAANSUhEUgAA...", "caption": "Foto do produto" }
                },
                "AudioBase64": {
                  "summary": "Audio via base64",
                  "value": { "to": "5511999999999", "type": "audio", "mediaBase64": "//uQAAAAAAAAAAAAAAAA..." }
                },
                "Documento": {
                  "summary": "Documento via URL publica",
                  "value": { "to": "5511999999999", "type": "document", "mediaUrl": "https://exemplo.com/arquivo.pdf", "fileName": "contrato.pdf", "caption": "Segue o contrato" }
                },
                "DocumentoBase64": {
                  "summary": "Documento via base64",
                  "value": { "to": "5511999999999", "type": "document", "mediaBase64": "JVBERi0xLjAKMSAwIG9iajw8...", "fileName": "contrato.pdf", "caption": "Segue o contrato" }
                },
                "Localizacao": {
                  "summary": "Localizacao",
                  "value": { "to": "5511999999999", "type": "location", "latitude": -23.5613, "longitude": -46.6565, "locationName": "Escritorio", "address": "Av. Paulista, 1000" }
                },
                "EnvioImediato": {
                  "summary": "Envio imediato (sem fila)",
                  "value": { "to": "5511999999999", "type": "text", "content": "Mensagem urgente", "enqueue": false }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mensagem enviada (envio direto, enqueue=false)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Mensagem enviada" },
                    "data": { "$ref": "#/components/schemas/SendMensagemResponse" }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Mensagem enviada",
                  "data": { "messageId": "3EB0123456789ABCDEF", "status": "sent" }
                }
              }
            }
          },
          "202": {
            "description": "Mensagem enfileirada (enqueue=true, padrao)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "boolean", "example": false },
                    "message": { "type": "string", "example": "Mensagem enfileirada para processamento" },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sessionId": { "type": "string", "example": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890" },
                        "to": { "type": "string", "example": "5511999999999" },
                        "type": { "type": "string", "example": "text" },
                        "queued": { "type": "boolean", "example": true }
                      }
                    }
                  }
                },
                "example": {
                  "error": false,
                  "message": "Mensagem enfileirada para processamento",
                  "data": { "sessionId": "inst_a1b2c3d4-e5f6-7890-abcd-ef1234567890", "to": "5511999999999", "type": "text", "queued": true }
                }
              }
            }
          },
          "400": {
            "description": "Instancia nao conectada ou validacao falhou",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": true, "message": "Instancia nao esta conectada. Inicie a sessao primeiro.", "data": null } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimit" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    }
  }
}