{ "openapi": "3.0.0", "info": { "title": "WhatsApp Oficial API", "description": "API REST para envio de mensagens via WhatsApp Cloud API (Meta). Suporta texto livre (janela 24h), templates aprovados e mídia.", "version": "1.0.0" }, "components": { "securitySchemes": { "apiKeyAuth": { "type": "apiKey", "in": "header", "name": "x-api-key" } }, "schemas": { "ConfigureAccountRequest": { "type": "object", "required": ["phone_number_id", "access_token"], "properties": { "phone_number_id": { "type": "string", "example": "123456789012345", "description": "ID do número no Meta for Developers" }, "access_token": { "type": "string", "example": "EAAxxxxx...", "description": "Token de acesso permanente do app Meta" }, "waba_id": { "type": "string", "example": "987654321098765", "description": "WhatsApp Business Account ID (necessário para listar templates)" } } }, "SendTextRequest": { "type": "object", "required": ["to", "type", "text"], "properties": { "to": { "type": "string", "example": "5511999998888" }, "type": { "type": "string", "enum": ["text"], "example": "text" }, "text": { "type": "string", "example": "Olá, tudo bem?" } } }, "SendTemplateRequest": { "type": "object", "required": ["to", "type", "templateName"], "properties": { "to": { "type": "string", "example": "5511999998888" }, "type": { "type": "string", "enum": ["template"], "example": "template" }, "templateName": { "type": "string", "example": "hello_world" }, "languageCode": { "type": "string", "example": "pt_BR", "default": "pt_BR" }, "components": { "type": "array", "description": "Parâmetros do template (body/header). Omita se o template não tiver variáveis.", "example": [{ "type": "body", "parameters": [{ "type": "text", "text": "João" }] }] } } }, "SendMediaRequest": { "type": "object", "required": ["to", "type", "mediaUrl"], "properties": { "to": { "type": "string", "example": "5511999998888" }, "type": { "type": "string", "enum": ["image", "document", "audio", "video"], "example": "image" }, "mediaUrl": { "type": "string", "example": "https://example.com/imagem.jpg" }, "caption": { "type": "string", "example": "Confira nossa promoção!" } } }, "SuccessResponse": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Operação realizada com sucesso." } } }, "ErrorResponse": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Descrição do erro." } } }, "AccountStatusResponse": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "accountId": { "type": "string", "example": "empresa1" }, "state": { "type": "string", "enum": ["CONNECTED", "INVALID_TOKEN", "ERROR"], "example": "CONNECTED" }, "displayPhoneNumber": { "type": "string", "example": "+55 11 99999-8888" }, "verifiedName": { "type": "string", "example": "Empresa XPTO" }, "qualityRating": { "type": "string", "example": "GREEN" } } } } }, "security": [{ "apiKeyAuth": [] }], "tags": [ { "name": "Account", "description": "Configuração e verificação de credenciais WABA (phone_number_id, access_token)" }, { "name": "Message", "description": "Envio de mensagens — texto livre (janela 24h), template aprovado ou mídia" }, { "name": "Templates", "description": "Listagem de templates aprovados na conta WABA" } ], "paths": { "/ping": { "get": { "tags": ["Account"], "summary": "Health check simples", "security": [], "responses": { "200": { "description": "pong" } } } }, "/account/configure/{accountId}": { "post": { "tags": ["Account"], "summary": "Salvar / atualizar credenciais WABA de uma conta", "parameters": [ { "name": "accountId", "in": "path", "required": true, "schema": { "type": "string" }, "example": "empresa1" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConfigureAccountRequest" } } } }, "responses": { "200": { "description": "Credenciais salvas", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessResponse" } } } }, "400": { "description": "Campos obrigatórios ausentes" }, "401": { "description": "API key inválida" } } } }, "/account/status/{accountId}": { "get": { "tags": ["Account"], "summary": "Verificar status da conexão com a Meta", "parameters": [ { "name": "accountId", "in": "path", "required": true, "schema": { "type": "string" }, "example": "empresa1" } ], "responses": { "200": { "description": "CONNECTED", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccountStatusResponse" } } } }, "200a": { "description": "INVALID_TOKEN ou ERROR" }, "401": { "description": "API key inválida" }, "404": { "description": "Conta não encontrada" } } } }, "/account/remove/{accountId}": { "delete": { "tags": ["Account"], "summary": "Remover credenciais de uma conta", "parameters": [ { "name": "accountId", "in": "path", "required": true, "schema": { "type": "string" }, "example": "empresa1" } ], "responses": { "200": { "description": "Conta removida", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessResponse" } } } }, "401": { "description": "API key inválida" }, "404": { "description": "Conta não encontrada" } } } }, "/message/send/{accountId}": { "post": { "tags": ["Message"], "summary": "Enviar mensagem (texto, template ou mídia)", "parameters": [ { "name": "accountId", "in": "path", "required": true, "schema": { "type": "string" }, "example": "empresa1" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/SendTextRequest" }, { "$ref": "#/components/schemas/SendTemplateRequest" }, { "$ref": "#/components/schemas/SendMediaRequest" } ] }, "examples": { "text": { "summary": "Texto livre (dentro da janela 24h)", "value": { "to": "5511999998888", "type": "text", "text": "Olá, tudo bem?" } }, "template": { "summary": "Template aprovado", "value": { "to": "5511999998888", "type": "template", "templateName": "hello_world", "languageCode": "pt_BR" } }, "template_params": { "summary": "Template com variável {{1}}", "value": { "to": "5511999998888", "type": "template", "templateName": "meu_template", "languageCode": "pt_BR", "components": [{ "type": "body", "parameters": [{ "type": "text", "text": "João" }] }] } }, "image": { "summary": "Imagem com legenda", "value": { "to": "5511999998888", "type": "image", "mediaUrl": "https://example.com/img.jpg", "caption": "Confira!" } } } } } }, "responses": { "200": { "description": "Mensagem enviada", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessResponse" } } } }, "400": { "description": "Parâmetros inválidos" }, "401": { "description": "API key inválida" }, "404": { "description": "Conta não encontrada" }, "502": { "description": "Erro retornado pela Meta" } } } }, "/templates/{accountId}": { "get": { "tags": ["Templates"], "summary": "Listar templates aprovados da conta WABA", "description": "Requer waba_id configurado via /account/configure.", "parameters": [ { "name": "accountId", "in": "path", "required": true, "schema": { "type": "string" }, "example": "empresa1" } ], "responses": { "200": { "description": "Lista de templates", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "templates": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "status": { "type": "string", "enum": ["APPROVED", "PENDING", "REJECTED"] }, "category": { "type": "string" }, "language": { "type": "string" } } } } } } } } }, "400": { "description": "waba_id não configurado" }, "401": { "description": "API key inválida" }, "404": { "description": "Conta não encontrada" } } } }, "/webhooks/meta": { "get": { "tags": ["Account"], "summary": "Verificação de webhook pelo Meta (hub.challenge)", "security": [], "parameters": [ { "name": "hub.mode", "in": "query", "schema": { "type": "string" } }, { "name": "hub.verify_token", "in": "query", "schema": { "type": "string" } }, { "name": "hub.challenge", "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Retorna hub.challenge se token válido" }, "403": { "description": "Token inválido" } } }, "post": { "tags": ["Account"], "summary": "Receber eventos do Meta e repassar ao whatsapp-sys", "security": [], "responses": { "200": { "description": "Recebido (sempre responde 200 imediatamente)" } } } } } }