Files
ecio b96d37ab11 feat: add pre-generated swagger.json; remove from .gitignore
swagger-autogen is a devDep not present in the Docker image.
Committing the generated file keeps the container self-contained.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 17:19:05 -03:00

270 lines
11 KiB
JSON

{
"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)" }
}
}
}
}
}