qwen_2.5_model / openapi.json
Muhammad Noman
Deploy OpenWA to Hugging Face Spaces
46252cd
Raw
History Blame Contribute Delete
211 kB
{
"openapi": "3.0.0",
"paths": {
"/api/audit": {
"get": {
"operationId": "AuditController_findAll",
"parameters": [
{
"name": "action",
"required": false,
"in": "query",
"schema": {
"enum": [
"api_key_created",
"api_key_updated",
"api_key_used",
"api_key_revoked",
"api_key_deleted",
"api_key_auth_failed",
"session_created",
"session_started",
"session_stopped",
"session_force_killed",
"session_deleted",
"session_qr_generated",
"session_connected",
"session_disconnected",
"message_sent",
"message_failed",
"webhook_created",
"webhook_deleted",
"webhook_triggered",
"webhook_failed",
"integration_instance_created",
"integration_instance_updated",
"integration_instance_secret_regenerated",
"integration_instance_deleted",
"infra_config_saved",
"infra_restart_requested",
"infra_data_exported",
"infra_data_imported",
"infra_storage_exported",
"infra_storage_imported"
],
"type": "string"
}
},
{
"name": "severity",
"required": false,
"in": "query",
"schema": {
"enum": [
"info",
"warn",
"error"
],
"type": "string"
}
},
{
"name": "sessionId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "apiKeyId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "Paginated list of audit logs"
}
},
"summary": "List audit logs with optional filters",
"tags": [
"audit"
]
}
},
"/api/auth/api-keys": {
"post": {
"operationId": "AuthController_create",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateApiKeyDto"
}
}
}
},
"responses": {
"201": {
"description": "API key created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiKeyCreatedResponseDto"
}
}
}
}
},
"summary": "Create a new API key (admin only)",
"tags": [
"auth"
]
},
"get": {
"operationId": "AuthController_findAll",
"parameters": [],
"responses": {
"200": {
"description": "All API keys (the plaintext key is never returned; only the keyPrefix).",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ApiKeyResponseDto"
}
}
}
}
}
},
"summary": "List all API keys (admin only)",
"tags": [
"auth"
]
}
},
"/api/auth/api-keys/{id}": {
"get": {
"operationId": "AuthController_findOne",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The API key (plaintext never returned; only the keyPrefix).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiKeyResponseDto"
}
}
}
}
},
"summary": "Get API key details (admin only)",
"tags": [
"auth"
]
},
"put": {
"operationId": "AuthController_update",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateApiKeyDto"
}
}
}
},
"responses": {
"200": {
"description": "The updated API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiKeyResponseDto"
}
}
}
},
"409": {
"description": "The change would remove the last usable admin key."
}
},
"summary": "Update API key (admin only)",
"tags": [
"auth"
]
},
"delete": {
"operationId": "AuthController_delete",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "API key deleted"
},
"409": {
"description": "The key is the last usable admin key."
}
},
"summary": "Delete API key (admin only)",
"tags": [
"auth"
]
}
},
"/api/auth/api-keys/{id}/revoke": {
"post": {
"operationId": "AuthController_revoke",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The revoked API key (isActive now false).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiKeyResponseDto"
}
}
}
},
"409": {
"description": "The key is the last usable admin key."
}
},
"summary": "Revoke API key (admin only)",
"tags": [
"auth"
]
}
},
"/api/auth/validate": {
"post": {
"operationId": "AuthValidateController_validate",
"parameters": [
{
"name": "X-API-Key",
"in": "header",
"description": "API key to validate",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "API key is valid"
},
"401": {
"description": "Invalid or missing API key"
}
},
"summary": "Validate an API key",
"tags": [
"auth"
]
}
},
"/api/sessions": {
"post": {
"operationId": "SessionController_create",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateSessionDto"
}
}
}
},
"responses": {
"201": {
"description": "Session created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
},
"409": {
"description": "Session name already exists"
}
},
"summary": "Create a new WhatsApp session",
"tags": [
"sessions"
]
},
"get": {
"operationId": "SessionController_findAll",
"parameters": [
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max sessions to return (1-1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of sessions to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of sessions",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
}
}
},
"summary": "List all sessions",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}": {
"get": {
"operationId": "SessionController_findOne",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Session details",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
},
"404": {
"description": "Session not found"
}
},
"summary": "Get session by ID",
"tags": [
"sessions"
]
},
"delete": {
"operationId": "SessionController_delete",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Session deleted"
},
"404": {
"description": "Session not found"
}
},
"summary": "Delete a session",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/start": {
"post": {
"operationId": "SessionController_start",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Session started",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
},
"400": {
"description": "Session already started"
},
"404": {
"description": "Session not found"
}
},
"summary": "Start a session and initialize WhatsApp connection",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/stop": {
"post": {
"operationId": "SessionController_stop",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Session stopped",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
},
"404": {
"description": "Session not found"
}
},
"summary": "Stop a session and disconnect WhatsApp",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/force-kill": {
"post": {
"operationId": "SessionController_forceKill",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Session force-killed",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionResponseDto"
}
}
}
},
"404": {
"description": "Session not found"
}
},
"summary": "Force-kill a stuck session (SIGKILL its wedged engine, then tear it down)",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/qr": {
"get": {
"operationId": "SessionController_getQRCode",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "QR code data",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QRCodeResponseDto"
}
}
}
},
"400": {
"description": "QR code not ready or session already authenticated"
},
"404": {
"description": "Session not found"
}
},
"summary": "Get QR code for session authentication",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/pairing-code": {
"post": {
"operationId": "SessionController_requestPairingCode",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RequestPairingCodeDto"
}
}
}
},
"responses": {
"201": {
"description": "Pairing code generated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PairingCodeResponseDto"
}
}
}
},
"400": {
"description": "Session not started or already authenticated"
},
"404": {
"description": "Session not found"
}
},
"summary": "Request an 8-char pairing code to link via phone number (alternative to QR)",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/groups": {
"get": {
"operationId": "SessionController_getGroups",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max groups to return (1–1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of groups to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of groups the session is a member of"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Get all groups for a session",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/chats": {
"get": {
"operationId": "SessionController_getChats",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max chats to return (1–1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of chats to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of active chats (most recent first)"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Get active chats for a session",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/chats/read": {
"post": {
"operationId": "SessionController_markChatRead",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MarkChatReadDto"
}
}
}
},
"responses": {
"200": {
"description": "Chat marked as read successfully"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Mark a chat as read/seen",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/chats/unread": {
"post": {
"operationId": "SessionController_markChatUnread",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MarkChatReadDto"
}
}
}
},
"responses": {
"200": {
"description": "Chat marked as unread successfully"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Mark a chat as unread",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/chats/delete": {
"post": {
"operationId": "SessionController_deleteChat",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeleteChatDto"
}
}
}
},
"responses": {
"200": {
"description": "Chat deleted successfully"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Delete a chat from the chat list (e.g. a group you have left)",
"tags": [
"sessions"
]
}
},
"/api/sessions/{id}/chats/typing": {
"post": {
"operationId": "SessionController_sendChatState",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendChatStateDto"
}
}
}
},
"responses": {
"200": {
"description": "Presence sent"
},
"404": {
"description": "Session not found"
}
},
"summary": "Send a typing/recording presence indicator to a chat (or clear it with 'paused')",
"tags": [
"sessions"
]
}
},
"/api/sessions/stats/overview": {
"get": {
"operationId": "SessionController_getStats",
"parameters": [],
"responses": {
"200": {
"description": "Session statistics including counts and memory usage"
}
},
"summary": "Get session statistics for multi-session monitoring",
"tags": [
"sessions"
]
}
},
"/api/sessions/{sessionId}/webhooks": {
"post": {
"operationId": "WebhookController_create",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateWebhookDto"
}
}
}
},
"responses": {
"201": {
"description": "Webhook created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookResponseDto"
}
}
}
}
},
"summary": "Create a webhook for the session",
"tags": [
"webhooks"
]
},
"get": {
"operationId": "WebhookController_findBySession",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of webhooks",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookResponseDto"
}
}
}
}
}
},
"summary": "List all webhooks for a session",
"tags": [
"webhooks"
]
}
},
"/api/sessions/{sessionId}/webhooks/{id}": {
"get": {
"operationId": "WebhookController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Webhook ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Webhook details",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookResponseDto"
}
}
}
},
"404": {
"description": "Webhook not found"
}
},
"summary": "Get a webhook by ID",
"tags": [
"webhooks"
]
},
"put": {
"operationId": "WebhookController_update",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Webhook ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateWebhookDto"
}
}
}
},
"responses": {
"200": {
"description": "Webhook updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookResponseDto"
}
}
}
},
"404": {
"description": "Webhook not found"
}
},
"summary": "Update a webhook",
"tags": [
"webhooks"
]
},
"delete": {
"operationId": "WebhookController_delete",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Webhook ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Webhook deleted"
},
"404": {
"description": "Webhook not found"
}
},
"summary": "Delete a webhook",
"tags": [
"webhooks"
]
}
},
"/api/sessions/{sessionId}/webhooks/{id}/test": {
"post": {
"operationId": "WebhookController_test",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Webhook ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Test result"
},
"404": {
"description": "Webhook not found"
}
},
"summary": "Test a webhook by sending a test payload",
"tags": [
"webhooks"
]
}
},
"/api/webhooks/delivery-failures": {
"get": {
"operationId": "WebhooksListController_deliveryFailures",
"parameters": [
{
"name": "sessionId",
"required": false,
"in": "query",
"description": "Filter to a single session",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max records to return (1-1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of records to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Permanently-failed webhook deliveries, most recent first"
}
},
"summary": "List recently-failed webhook deliveries (all retries exhausted)",
"tags": [
"webhooks"
]
}
},
"/api/webhooks": {
"get": {
"operationId": "WebhooksListController_findAll",
"parameters": [
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max webhooks to return (1-1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of webhooks to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of webhooks",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookResponseDto"
}
}
}
}
}
},
"summary": "List webhooks visible to the calling key (scoped to its allowed sessions)",
"tags": [
"webhooks"
]
}
},
"/api/sessions/{sessionId}/messages": {
"get": {
"operationId": "MessageController_getMessages",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": false,
"in": "query",
"description": "Filter by chat ID",
"schema": {
"type": "string"
}
},
{
"name": "from",
"required": false,
"in": "query",
"description": "Filter by sender. A phone also matches messages from a lid that resolves to it.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max messages to return (default 50)",
"schema": {
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Offset for pagination",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "Message history"
}
},
"summary": "Get message history for a session",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-text": {
"post": {
"operationId": "MessageController_sendText",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendTextMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Message sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
},
"404": {
"description": "Session not found"
}
},
"summary": "Send a text message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-template": {
"post": {
"operationId": "MessageController_sendTemplate",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendTemplateMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Template rendered and sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
},
"404": {
"description": "Session or template not found"
}
},
"summary": "Render a stored text template and send it as a text message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-image": {
"post": {
"operationId": "MessageController_sendImage",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendMediaMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Image sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
}
},
"summary": "Send an image message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-video": {
"post": {
"operationId": "MessageController_sendVideo",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendMediaMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Video sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
}
},
"summary": "Send a video message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-audio": {
"post": {
"operationId": "MessageController_sendAudio",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendAudioMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Audio sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
}
},
"summary": "Send an audio/voice message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-document": {
"post": {
"operationId": "MessageController_sendDocument",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendMediaMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Document sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
}
},
"summary": "Send a document/file",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-location": {
"post": {
"operationId": "MessageController_sendLocation",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendLocationDto"
}
}
}
},
"responses": {
"201": {
"description": "Location sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Send a location message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-contact": {
"post": {
"operationId": "MessageController_sendContact",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendContactDto"
}
}
}
},
"responses": {
"201": {
"description": "Contact sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Send a contact card message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-sticker": {
"post": {
"operationId": "MessageController_sendSticker",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendMediaMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Sticker sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Send a sticker message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-poll": {
"post": {
"operationId": "MessageController_sendPoll",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendPollDto"
}
}
}
},
"responses": {
"201": {
"description": "Poll sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Send a native WhatsApp poll",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/reply": {
"post": {
"operationId": "MessageController_reply",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Reply sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Reply to a message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/forward": {
"post": {
"operationId": "MessageController_forward",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ForwardMessageDto"
}
}
}
},
"responses": {
"201": {
"description": "Message forwarded",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
}
},
"summary": "Forward a message to another chat",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/react": {
"post": {
"operationId": "MessageController_react",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReactMessageDto"
}
}
}
},
"responses": {
"200": {
"description": "Reaction added or removed. Send empty emoji to remove reaction."
},
"400": {
"description": "Session not active or message not found"
}
},
"summary": "Add or remove a reaction to a message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/{chatId}/history": {
"get": {
"description": "Reads messages directly from the WhatsApp client for the given chat, bypassing the local DB. Useful for retrieving messages that arrived before the gateway was started.",
"operationId": "MessageController_getChatHistory",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": true,
"in": "path",
"description": "Chat ID (e.g. 1234567890@c.us or groupId@g.us)",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max messages to return (default 50)",
"schema": {
"type": "number"
}
},
{
"name": "includeMedia",
"required": false,
"in": "query",
"description": "When true, downloads media (base64) for messages that have it. Slower; default false.",
"schema": {
"type": "boolean"
}
},
{
"name": "deep",
"required": false,
"in": "query",
"description": "When true, raises the limit ceiling from 100 to 2000 for reaching further back in history (whatsapp-web.js only; loads earlier messages on demand). Forces metadata-only (includeMedia is ignored). Large/slow requests may increase WhatsApp rate-limiting risk; default false.",
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"description": "Chat history (most recent messages)"
}
},
"summary": "Fetch chat history live from WhatsApp",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/{chatId}/{messageId}/reactions": {
"get": {
"operationId": "MessageController_getReactions",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": true,
"in": "path",
"description": "Chat ID containing the message",
"schema": {
"type": "string"
}
},
{
"name": "messageId",
"required": true,
"in": "path",
"description": "Message ID to get reactions for",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of reactions with senders"
}
},
"summary": "Get reactions for a specific message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/delete": {
"post": {
"operationId": "MessageController_deleteMessage",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeleteMessageDto"
}
}
}
},
"responses": {
"200": {
"description": "Message deleted"
},
"400": {
"description": "Session not active or message not found"
}
},
"summary": "Delete a message",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/edit": {
"post": {
"operationId": "MessageController_edit",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EditMessageDto"
}
}
}
},
"responses": {
"200": {
"description": "Message edited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active, invalid request, or the send was blocked by a plugin"
},
"403": {
"description": "The message was not sent by this account, or the engine refused the edit"
},
"404": {
"description": "Message not found"
}
},
"summary": "Edit the text of a message sent by this account",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/send-bulk": {
"post": {
"operationId": "MessageController_sendBulk",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendBulkMessageDto"
}
}
}
},
"responses": {
"202": {
"description": "Batch created and processing started",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkMessageResponseDto"
}
}
}
},
"400": {
"description": "Session not active or invalid request"
}
},
"summary": "Send messages to multiple recipients (async batch processing)",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/batch/{batchId}": {
"get": {
"operationId": "MessageController_getBatchStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "batchId",
"required": true,
"in": "path",
"description": "Batch ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Batch status and progress"
},
"404": {
"description": "Batch not found"
}
},
"summary": "Get batch processing status",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/messages/batch/{batchId}/cancel": {
"post": {
"operationId": "MessageController_cancelBatch",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "batchId",
"required": true,
"in": "path",
"description": "Batch ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Batch cancelled"
},
"400": {
"description": "Batch already completed or cancelled"
},
"404": {
"description": "Batch not found"
}
},
"summary": "Cancel a running batch",
"tags": [
"messages"
]
}
},
"/api/sessions/{sessionId}/templates": {
"post": {
"operationId": "TemplateController_create",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateTemplateDto"
}
}
}
},
"responses": {
"201": {
"description": "Template created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplateResponseDto"
}
}
}
}
},
"summary": "Create a message template for the session",
"tags": [
"templates"
]
},
"get": {
"operationId": "TemplateController_findBySession",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of templates",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TemplateResponseDto"
}
}
}
}
}
},
"summary": "List all templates for a session",
"tags": [
"templates"
]
}
},
"/api/sessions/{sessionId}/templates/{id}": {
"get": {
"operationId": "TemplateController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Template ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Template details",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplateResponseDto"
}
}
}
},
"404": {
"description": "Template not found"
}
},
"summary": "Get a template by ID",
"tags": [
"templates"
]
},
"put": {
"operationId": "TemplateController_update",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Template ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateTemplateDto"
}
}
}
},
"responses": {
"200": {
"description": "Template updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplateResponseDto"
}
}
}
},
"404": {
"description": "Template not found"
}
},
"summary": "Update a template",
"tags": [
"templates"
]
},
"delete": {
"operationId": "TemplateController_delete",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": true,
"in": "path",
"description": "Template ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Template deleted"
},
"404": {
"description": "Template not found"
}
},
"summary": "Delete a template",
"tags": [
"templates"
]
}
},
"/api/health": {
"get": {
"operationId": "HealthController_check",
"parameters": [],
"responses": {
"200": {
"description": "Application is healthy"
}
},
"summary": "Basic health check",
"tags": [
"health"
],
"security": []
}
},
"/api/health/live": {
"get": {
"operationId": "HealthController_liveness",
"parameters": [],
"responses": {
"200": {
"description": "Application is alive"
}
},
"summary": "Liveness probe for Kubernetes",
"tags": [
"health"
],
"security": []
}
},
"/api/health/ready": {
"get": {
"operationId": "HealthController_readiness",
"parameters": [],
"responses": {
"200": {
"description": "Application is ready to accept traffic"
},
"503": {
"description": "A required dependency is down"
}
},
"summary": "Readiness probe — verifies the auth/audit + data databases respond",
"tags": [
"health"
],
"security": []
}
},
"/api/settings": {
"get": {
"operationId": "SettingsController_get",
"parameters": [],
"responses": {
"200": {
"description": "Current settings"
}
},
"summary": "Get application settings",
"tags": [
"settings"
]
},
"put": {
"operationId": "SettingsController_update",
"parameters": [],
"responses": {
"501": {
"description": "Settings are derived from environment configuration and cannot be changed at runtime"
}
},
"summary": "Settings are read-only at runtime (environment-derived)",
"tags": [
"settings"
]
}
},
"/api/infra/status": {
"get": {
"operationId": "InfraController_getStatus",
"parameters": [],
"responses": {
"200": {
"description": "Infrastructure status"
}
},
"summary": "Get infrastructure status",
"tags": [
"infrastructure"
]
}
},
"/api/infra/engines": {
"get": {
"operationId": "InfraController_getEngines",
"parameters": [],
"responses": {
"200": {
"description": "List of available engines"
}
},
"summary": "Get available WhatsApp engines",
"tags": [
"infrastructure"
]
}
},
"/api/infra/engines/current": {
"get": {
"operationId": "InfraController_getCurrentEngine",
"parameters": [],
"responses": {
"200": {
"description": "Current engine info"
}
},
"summary": "Get current active engine",
"tags": [
"infrastructure"
]
}
},
"/api/infra/config": {
"get": {
"operationId": "InfraController_getConfig",
"parameters": [],
"responses": {
"200": {
"description": "Saved configuration (secrets omitted)"
}
},
"summary": "Read the saved infrastructure configuration for the dashboard form",
"tags": [
"infrastructure"
]
},
"put": {
"operationId": "InfraController_saveConfig",
"parameters": [],
"requestBody": {
"required": true,
"description": "Configuration to save",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SaveConfigDto"
}
}
}
},
"responses": {
"200": {
"description": "Configuration saved"
}
},
"summary": "Save infrastructure configuration to .env file",
"tags": [
"infrastructure"
]
}
},
"/api/infra/restart": {
"post": {
"operationId": "InfraController_requestRestart",
"parameters": [],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RestartDto"
}
}
}
},
"responses": {
"200": {
"description": "Server will restart with new profiles"
}
},
"summary": "Request server restart with Docker orchestration",
"tags": [
"infrastructure"
]
}
},
"/api/infra/health": {
"get": {
"operationId": "InfraController_healthCheck",
"parameters": [],
"responses": {
"200": {
"description": "Server is healthy"
}
},
"summary": "Health check endpoint",
"tags": [
"infrastructure"
],
"security": []
}
},
"/api/infra/export-data": {
"get": {
"operationId": "InfraController_exportData",
"parameters": [],
"responses": {
"200": {
"description": "Exported data as JSON"
}
},
"summary": "Export all data from Data DB for migration",
"tags": [
"infrastructure"
]
}
},
"/api/infra/import-data": {
"post": {
"operationId": "InfraController_importData",
"parameters": [],
"requestBody": {
"required": true,
"description": "Exported data from export-data endpoint",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"tables": {
"type": "object",
"properties": {
"sessions": {
"type": "array"
},
"webhooks": {
"type": "array"
},
"messages": {
"type": "array"
},
"messageBatches": {
"type": "array"
}
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Data imported successfully"
}
},
"summary": "Import data to Data DB (replaces existing data)",
"tags": [
"infrastructure"
]
}
},
"/api/infra/storage/files/count": {
"get": {
"operationId": "InfraController_getStorageFileCount",
"parameters": [],
"responses": {
"200": {
"description": "File count and size"
}
},
"summary": "Get file count in current storage",
"tags": [
"infrastructure"
]
}
},
"/api/infra/storage/export": {
"get": {
"operationId": "InfraController_exportStorage",
"parameters": [],
"responses": {
"200": {
"description": "Tar.gz archive stream"
}
},
"summary": "Export all storage files as tar.gz",
"tags": [
"infrastructure"
]
}
},
"/api/infra/storage/import": {
"post": {
"operationId": "InfraController_importStorage",
"parameters": [],
"requestBody": {
"required": true,
"description": "Path to tar.gz file to import",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
},
"responses": {
"200": {
"description": "Import result"
}
},
"summary": "Import storage files from tar.gz",
"tags": [
"infrastructure"
]
}
},
"/api/sessions/{sessionId}/contacts": {
"get": {
"operationId": "ContactController_findAll",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max contacts to return (1–1000, default 1000)",
"schema": {
"type": "string"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Number of contacts to skip (for paging)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of contacts"
},
"400": {
"description": "Session not ready"
},
"404": {
"description": "Session not found"
}
},
"summary": "Get all contacts for a session",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/profile-pictures": {
"get": {
"description": "One request for a whole chat sidebar — avoids the burst of parallel single fetches that would exhaust the per-IP throttle. Engine lookups run 3 at a time; per-id failures return null.",
"operationId": "ContactController_getProfilePictures",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "ids",
"required": true,
"in": "query",
"description": "Comma-separated contact ids (max 50 used)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"summary": "Batch-resolve profile picture URLs for up to 50 contacts",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/{contactId}": {
"get": {
"operationId": "ContactController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"description": "Contact ID (e.g., 628xxx@c.us)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Contact details"
},
"404": {
"description": "Contact not found"
}
},
"summary": "Get a specific contact by ID",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/check/{number}": {
"get": {
"description": "Returns whether the number is a registered WhatsApp account and its canonical id. Use this to pre-validate a recipient before sending: the send endpoints return 201 on accepting a message even for numbers that are not on WhatsApp, so this is the only way to confirm a new number is reachable before you send to it.",
"operationId": "ContactController_checkNumber",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "number",
"required": true,
"in": "path",
"description": "Phone number to check (e.g., 628123456789)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Number existence check result"
}
},
"summary": "Check if a phone number exists on WhatsApp",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/{contactId}/profile-picture": {
"get": {
"operationId": "ContactController_getProfilePicture",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"description": "Contact ID (e.g., 628xxx@c.us)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Profile picture URL"
}
},
"summary": "Get profile picture URL for a contact",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/{contactId}/phone": {
"get": {
"operationId": "ContactController_resolvePhone",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"description": "Contact ID / JID to resolve (e.g., an @lid)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Resolved phone number (MSISDN digits), or null when the engine cannot map it"
}
},
"summary": "Resolve a contact id (e.g. an @lid) to a phone number — best-effort",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/contacts/{contactId}/block": {
"post": {
"operationId": "ContactController_blockContact",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"description": "Contact ID (e.g., 628xxx@c.us)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Contact blocked"
}
},
"summary": "Block a contact",
"tags": [
"contacts"
]
},
"delete": {
"operationId": "ContactController_unblockContact",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"description": "Contact ID (e.g., 628xxx@c.us)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Contact unblocked"
}
},
"summary": "Unblock a contact",
"tags": [
"contacts"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}": {
"get": {
"operationId": "GroupController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID (e.g., 120363xxx@g.us)",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Group details with participants"
},
"404": {
"description": "Group not found"
}
},
"summary": "Get detailed group info",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/join": {
"post": {
"operationId": "GroupController_join",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/JoinGroupDto"
}
}
}
},
"responses": {
"200": {
"description": "Joined the group"
},
"400": {
"description": "Invalid or expired invite code, or session is not started"
}
},
"summary": "Join a group via invite code",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/settings": {
"get": {
"operationId": "GroupController_getSettings",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Group settings"
},
"404": {
"description": "Group not found"
}
},
"summary": "Get group settings (announce / locked / ephemeral timer)",
"tags": [
"groups"
]
},
"put": {
"operationId": "GroupController_updateSettings",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GroupSettingsDto"
}
}
}
},
"responses": {
"200": {
"description": "Group settings updated"
},
"400": {
"description": "No setting provided, or a value is not a boolean"
},
"403": {
"description": "The engine refused the change (the account is not a group admin)"
},
"404": {
"description": "Group not found"
},
"501": {
"description": "The active engine does not support a requested setting"
}
},
"summary": "Update group settings (announce / locked / ephemeral timer)",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups": {
"post": {
"operationId": "GroupController_create",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateGroupDto"
}
}
}
},
"responses": {
"201": {
"description": "Group created"
}
},
"summary": "Create a new group",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/participants": {
"post": {
"operationId": "GroupController_addParticipants",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ParticipantsDto"
}
}
}
},
"responses": {
"200": {
"description": "Participants added"
}
},
"summary": "Add participants to a group",
"tags": [
"groups"
]
},
"delete": {
"operationId": "GroupController_removeParticipants",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ParticipantsDto"
}
}
}
},
"responses": {
"200": {
"description": "Participants removed"
}
},
"summary": "Remove participants from a group",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/participants/promote": {
"post": {
"operationId": "GroupController_promoteParticipants",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ParticipantsDto"
}
}
}
},
"responses": {
"200": {
"description": "Participants promoted"
}
},
"summary": "Promote participants to admin",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/participants/demote": {
"post": {
"operationId": "GroupController_demoteParticipants",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ParticipantsDto"
}
}
}
},
"responses": {
"200": {
"description": "Participants demoted"
}
},
"summary": "Demote participants from admin",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/subject": {
"put": {
"operationId": "GroupController_setSubject",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GroupSubjectDto"
}
}
}
},
"responses": {
"200": {
"description": "Subject updated"
}
},
"summary": "Change group name/subject",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/description": {
"put": {
"operationId": "GroupController_setDescription",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GroupDescriptionDto"
}
}
}
},
"responses": {
"200": {
"description": "Description updated"
}
},
"summary": "Change group description",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/leave": {
"post": {
"operationId": "GroupController_leave",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Left the group"
}
},
"summary": "Leave a group",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/invite-code": {
"get": {
"operationId": "GroupController_getInviteCode",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Group invite code"
}
},
"summary": "Get group invite code/link",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/groups/{groupId}/invite-code/revoke": {
"post": {
"operationId": "GroupController_revokeInviteCode",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "groupId",
"required": true,
"in": "path",
"description": "Group ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "New invite code generated"
}
},
"summary": "Revoke group invite code and generate new one",
"tags": [
"groups"
]
}
},
"/api/sessions/{sessionId}/profile/name": {
"put": {
"operationId": "ProfileController_setName",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetProfileNameDto"
}
}
}
},
"responses": {
"200": {
"description": "Profile name updated"
},
"400": {
"description": "Session is not started"
},
"403": {
"description": "The engine refused the name change"
}
},
"summary": "Set the account display name",
"tags": [
"profile"
]
}
},
"/api/sessions/{sessionId}/profile/status": {
"put": {
"operationId": "ProfileController_setStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetProfileStatusDto"
}
}
}
},
"responses": {
"200": {
"description": "Profile status updated"
},
"400": {
"description": "Session is not started"
}
},
"summary": "Set the account about/status text",
"tags": [
"profile"
]
}
},
"/api/sessions/{sessionId}/profile/picture": {
"put": {
"operationId": "ProfileController_setPicture",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetProfilePictureDto"
}
}
}
},
"responses": {
"200": {
"description": "Profile picture updated"
},
"400": {
"description": "Neither url nor base64 provided, base64 without mimetype, or session is not started"
},
"403": {
"description": "The engine refused the picture change"
},
"413": {
"description": "Decoded base64 image exceeds the configured media cap"
}
},
"summary": "Set the account profile picture (URL or base64 image)",
"tags": [
"profile"
]
}
},
"/api/sessions/{sessionId}/calls/{callId}/reject": {
"post": {
"operationId": "CallController_reject",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "callId",
"required": true,
"in": "path",
"description": "Call ID from the call.received event",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Call rejected"
},
"400": {
"description": "Session is not started"
},
"404": {
"description": "Call not found or no longer ringing"
}
},
"summary": "Reject a ringing incoming call",
"tags": [
"calls"
]
}
},
"/api/sessions/{sessionId}/labels": {
"get": {
"operationId": "LabelController_findAll",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of labels"
},
"400": {
"description": "Session not ready or not a business account"
},
"404": {
"description": "Session not found"
}
},
"summary": "Get all labels (WhatsApp Business only)",
"tags": [
"labels"
]
}
},
"/api/sessions/{sessionId}/labels/{labelId}": {
"get": {
"operationId": "LabelController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "labelId",
"required": true,
"in": "path",
"description": "Label ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Label details"
},
"404": {
"description": "Label not found"
}
},
"summary": "Get a specific label by ID",
"tags": [
"labels"
]
}
},
"/api/sessions/{sessionId}/labels/chat/{chatId}": {
"get": {
"operationId": "LabelController_getChatLabels",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": true,
"in": "path",
"description": "Chat ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of labels for the chat"
}
},
"summary": "Get labels for a specific chat",
"tags": [
"labels"
]
},
"post": {
"operationId": "LabelController_addLabelToChat",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": true,
"in": "path",
"description": "Chat ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"labelId": {
"type": "string",
"description": "Label ID to add"
}
},
"required": [
"labelId"
]
}
}
}
},
"responses": {
"200": {
"description": "Label added to chat"
},
"422": {
"description": "Labels require a WhatsApp Business account, or the chat type has no labels"
}
},
"summary": "Add a label to a chat",
"tags": [
"labels"
]
}
},
"/api/sessions/{sessionId}/labels/chat/{chatId}/{labelId}": {
"delete": {
"operationId": "LabelController_removeLabelFromChat",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": true,
"in": "path",
"description": "Chat ID",
"schema": {
"type": "string"
}
},
{
"name": "labelId",
"required": true,
"in": "path",
"description": "Label ID to remove",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Label removed from chat"
},
"422": {
"description": "Labels require a WhatsApp Business account, or the chat type has no labels"
}
},
"summary": "Remove a label from a chat",
"tags": [
"labels"
]
}
},
"/api/sessions/{sessionId}/channels": {
"get": {
"operationId": "ChannelController_findAll",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of subscribed channels"
},
"400": {
"description": "Session not ready"
}
},
"summary": "Get all subscribed channels/newsletters",
"tags": [
"channels"
]
}
},
"/api/sessions/{sessionId}/channels/{channelId}": {
"get": {
"operationId": "ChannelController_findOne",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "channelId",
"required": true,
"in": "path",
"description": "Channel ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Channel details"
},
"404": {
"description": "Channel not found"
}
},
"summary": "Get a specific channel by ID",
"tags": [
"channels"
]
},
"delete": {
"operationId": "ChannelController_unsubscribe",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "channelId",
"required": true,
"in": "path",
"description": "Channel ID to unsubscribe from",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successfully unsubscribed from channel"
}
},
"summary": "Unsubscribe from a channel",
"tags": [
"channels"
]
}
},
"/api/sessions/{sessionId}/channels/{channelId}/messages": {
"get": {
"operationId": "ChannelController_getMessages",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
},
{
"name": "channelId",
"required": true,
"in": "path",
"description": "Channel ID",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max messages to return (default 50)",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "List of channel messages"
}
},
"summary": "Get messages from a channel",
"tags": [
"channels"
]
}
},
"/api/sessions/{sessionId}/channels/subscribe": {
"post": {
"operationId": "ChannelController_subscribe",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"description": "Session ID",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"inviteCode": {
"type": "string",
"description": "Channel invite code (from channel link)",
"example": "ABC123xyz"
}
},
"required": [
"inviteCode"
]
}
}
}
},
"responses": {
"201": {
"description": "Successfully subscribed to channel"
}
},
"summary": "Subscribe to a channel using invite code",
"tags": [
"channels"
]
}
},
"/api/stats/overview": {
"get": {
"operationId": "StatsController_getOverview",
"parameters": [],
"responses": {
"200": {
"description": "Cross-session aggregate statistics (sessions, messages, etc.)."
}
},
"summary": "Get overall statistics",
"tags": [
"statistics"
]
}
},
"/api/stats/messages": {
"get": {
"operationId": "StatsController_getMessageStats",
"parameters": [],
"responses": {
"200": {
"description": "Message statistics with a time series for the requested period."
}
},
"summary": "Get message statistics with time series",
"tags": [
"statistics"
]
}
},
"/api/stats/sessions/{sessionId}": {
"get": {
"operationId": "StatsController_getSessionStats",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Per-session statistics for the requested session."
}
},
"summary": "Get statistics for a specific session",
"tags": [
"statistics"
]
}
},
"/api/sessions/{sessionId}/status": {
"get": {
"operationId": "StatusController_getStatuses",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Status updates visible to the session, grouped by contact."
}
},
"summary": "Get all contact status updates",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/status/{contactId}": {
"get": {
"operationId": "StatusController_getContactStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "contactId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Status updates from the requested contact."
}
},
"summary": "Get status updates from a specific contact",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/status/send-text": {
"post": {
"operationId": "StatusController_sendTextStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendTextStatusDto"
}
}
}
},
"responses": {
"201": {
"description": "Text status posted. The recipients allow-list is honored on Baileys only; whatsapp-web.js broadcasts to the account's status-privacy audience."
},
"400": {
"description": "Invalid request, or the post was blocked by a plugin."
}
},
"summary": "Post a text status",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/status/send-image": {
"post": {
"operationId": "StatusController_sendImageStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendImageStatusDto"
}
}
}
},
"responses": {
"201": {
"description": "Image status posted. The recipients allow-list is honored on Baileys only; whatsapp-web.js broadcasts to the account's status-privacy audience."
},
"400": {
"description": "Neither url nor base64 provided, or the post was blocked by a plugin."
},
"413": {
"description": "Base64 media exceeds MEDIA_DOWNLOAD_MAX_BYTES."
}
},
"summary": "Post an image status",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/status/send-video": {
"post": {
"operationId": "StatusController_sendVideoStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendVideoStatusDto"
}
}
}
},
"responses": {
"201": {
"description": "Video status posted. The recipients allow-list is honored on Baileys only; whatsapp-web.js broadcasts to the account's status-privacy audience."
},
"400": {
"description": "Neither url nor base64 provided, or the post was blocked by a plugin."
},
"413": {
"description": "Base64 media exceeds MEDIA_DOWNLOAD_MAX_BYTES."
}
},
"summary": "Post a video status",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/status/{statusId}": {
"delete": {
"operationId": "StatusController_deleteStatus",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "statusId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Status deleted."
}
},
"summary": "Delete own status",
"tags": [
"status"
]
}
},
"/api/sessions/{sessionId}/catalog": {
"get": {
"operationId": "CatalogController_getCatalog",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Always null on whatsapp-web.js: catalog reads are not implemented on either engine."
},
"501": {
"description": "Not supported by the active engine: Baileys does not implement catalog reads."
}
},
"summary": "Get business catalog info (not implemented by any engine)",
"tags": [
"catalog"
]
}
},
"/api/sessions/{sessionId}/catalog/products": {
"get": {
"operationId": "CatalogController_getProducts",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "page",
"required": false,
"in": "query",
"description": "Result page (1-based).",
"schema": {
"minimum": 1,
"example": 1,
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Page size.",
"schema": {
"minimum": 1,
"example": 20,
"type": "number"
}
}
],
"responses": {
"200": {
"description": "Always an empty page on whatsapp-web.js: catalog reads are not implemented on either engine."
},
"501": {
"description": "Not supported by the active engine: Baileys does not implement catalog reads."
}
},
"summary": "List catalog products (not implemented by any engine)",
"tags": [
"catalog"
]
}
},
"/api/sessions/{sessionId}/catalog/products/{productId}": {
"get": {
"operationId": "CatalogController_getProduct",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "productId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Always null on whatsapp-web.js: catalog reads are not implemented on either engine."
},
"501": {
"description": "Not supported by the active engine: Baileys does not implement catalog reads."
}
},
"summary": "Get a specific product (not implemented by any engine)",
"tags": [
"catalog"
]
}
},
"/api/sessions/{sessionId}/messages/send-product": {
"post": {
"operationId": "CatalogController_sendProduct",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendProductDto"
}
}
}
},
"responses": {
"501": {
"description": "Not supported by the active engine: no engine can send product messages."
}
},
"summary": "Send a product message (not supported by any engine)",
"tags": [
"catalog"
]
}
},
"/api/sessions/{sessionId}/messages/send-catalog": {
"post": {
"operationId": "CatalogController_sendCatalog",
"parameters": [
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SendCatalogDto"
}
}
}
},
"responses": {
"501": {
"description": "Not supported by the active engine: no engine can send catalog links."
}
},
"summary": "Send catalog link (not supported by any engine)",
"tags": [
"catalog"
]
}
},
"/api/plugins": {
"get": {
"operationId": "PluginsController_findAll",
"parameters": [],
"responses": {
"200": {
"description": "List of all plugins"
}
},
"summary": "List all plugins",
"tags": [
"plugins"
]
}
},
"/api/plugins/install": {
"post": {
"operationId": "PluginsController_install",
"parameters": [],
"responses": {
"201": {
"description": "Plugin installed"
},
"400": {
"description": "Invalid package"
},
"409": {
"description": "Plugin already installed"
}
},
"summary": "Install a plugin from an uploaded .zip package",
"tags": [
"plugins"
]
}
},
"/api/plugins/install-url": {
"post": {
"operationId": "PluginsController_installFromUrl",
"parameters": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstallFromUrlDto"
}
}
}
},
"responses": {
"201": {
"description": "Plugin installed"
},
"400": {
"description": "Invalid URL, download failed, or invalid package"
},
"409": {
"description": "Plugin already installed"
}
},
"summary": "Install a plugin by downloading its .zip from a URL (SSRF-guarded)",
"tags": [
"plugins"
]
}
},
"/api/plugins/catalog": {
"get": {
"operationId": "PluginsController_catalog",
"parameters": [],
"responses": {
"200": {
"description": "Catalog entries"
},
"400": {
"description": "Catalog could not be fetched or parsed"
}
},
"summary": "List the remote plugin catalog, annotated with install state",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}": {
"get": {
"operationId": "PluginsController_findOne",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Plugin details"
},
"404": {
"description": "Plugin not found"
}
},
"summary": "Get plugin by ID",
"tags": [
"plugins"
]
},
"delete": {
"operationId": "PluginsController_uninstall",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Plugin uninstalled"
},
"400": {
"description": "Cannot uninstall (e.g. built-in)"
},
"404": {
"description": "Plugin not found"
}
},
"summary": "Uninstall a plugin (removes its files; built-ins are protected)",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/enable": {
"post": {
"operationId": "PluginsController_enable",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Plugin enabled successfully"
}
},
"summary": "Enable a plugin",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/disable": {
"post": {
"operationId": "PluginsController_disable",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Plugin disabled successfully"
}
},
"summary": "Disable a plugin",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/config": {
"put": {
"operationId": "PluginsController_updateConfig",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PluginConfigDto"
}
}
}
},
"responses": {
"200": {
"description": "Plugin configuration updated"
}
},
"summary": "Update plugin configuration",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/config-ui": {
"get": {
"operationId": "PluginsController_getConfigUi",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Config UI HTML"
},
"404": {
"description": "Plugin not found or has no config UI"
}
},
"summary": "Serve a plugin's sandboxed config-UI entry HTML (for an iframe srcdoc)",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/config/{sessionId}": {
"put": {
"operationId": "PluginsController_updateSessionConfig",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "sessionId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PluginConfigDto"
}
}
}
},
"responses": {
"200": {
"description": "Per-session plugin configuration updated"
},
"400": {
"description": "Plugin is global (not session-scoped)"
},
"404": {
"description": "Plugin not found"
}
},
"summary": "Set a plugin config override for a specific session (empty = clear it)",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/sessions": {
"put": {
"operationId": "PluginsController_updateSessions",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PluginSessionsDto"
}
}
}
},
"responses": {
"200": {
"description": "Plugin session activation updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PluginDto"
}
}
}
},
"400": {
"description": "Plugin is global (not session-scoped)"
},
"404": {
"description": "Plugin not found"
}
},
"summary": "Set which sessions a session-scoped plugin is activated for (['*'] = all)",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/update": {
"post": {
"operationId": "PluginsController_update",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstallFromUrlDto"
}
}
}
},
"responses": {
"201": {
"description": "Plugin updated"
},
"400": {
"description": "Invalid URL/package, id mismatch, or built-in"
},
"404": {
"description": "Plugin not found"
}
},
"summary": "Update an installed plugin in place from a URL (preserves config + enabled state)",
"tags": [
"plugins"
]
}
},
"/api/plugins/{id}/health": {
"get": {
"operationId": "PluginsController_healthCheck",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Plugin health status"
}
},
"summary": "Check plugin health",
"tags": [
"plugins"
]
}
},
"/api/ingress/{pluginId}/{instanceId}/{path}": {
"get": {
"operationId": "IngressController_receive_get",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"post": {
"operationId": "IngressController_receive_post",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"put": {
"operationId": "IngressController_receive_put",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"delete": {
"operationId": "IngressController_receive_delete",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"patch": {
"operationId": "IngressController_receive_patch",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"options": {
"operationId": "IngressController_receive_options",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"head": {
"operationId": "IngressController_receive_head",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
},
"search": {
"operationId": "IngressController_receive_search",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "GET verification challenge echo, or a duplicate delivery already persisted (idempotent re-delivery). Not the primary success path — see 202."
},
"202": {
"description": "Webhook accepted and queued for async plugin processing (the primary success path)."
},
"401": {
"description": "Signature verification failed (missing, stale, or wrong secret)."
},
"403": {
"description": "GET verification challenge failed (verifyToken mismatch)."
},
"404": {
"description": "Unknown pluginId/instanceId, or no route claimed by the plugin."
},
"413": {
"description": "Request body exceeds the route maxBodyBytes limit."
},
"429": {
"description": "Per-instance rate limit exceeded (INGRESS_INSTANCE_LIMIT)."
}
},
"tags": [
"integration"
],
"security": []
}
},
"/api/integration/instances/{pluginId}/{instanceId}/redrive": {
"post": {
"operationId": "RedriveController_redriveInstance",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"201": {
"description": "One bounded batch of dead-lettered ingress deliveries re-dispatched, with remaining depth."
}
},
"tags": [
"integration"
]
}
},
"/api/integration/plugins/{pluginId}/instances": {
"post": {
"operationId": "IntegrationInstanceController_create",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateInstanceDto"
}
}
}
},
"responses": {
"201": {
"description": "Instance created. The plaintext ingress secret and verifyToken are revealed once in this response — store them immediately (both masked on every later read).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstanceView"
}
}
}
}
},
"tags": [
"integration"
]
},
"get": {
"operationId": "IntegrationInstanceController_list",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Instances for the plugin (secrets masked).",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/InstanceView"
}
}
}
}
}
},
"tags": [
"integration"
]
}
},
"/api/integration/plugins/{pluginId}/instances/{instanceId}": {
"get": {
"operationId": "IntegrationInstanceController_getOne",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The instance (secret masked).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstanceView"
}
}
}
}
},
"tags": [
"integration"
]
},
"patch": {
"operationId": "IntegrationInstanceController_patch",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateInstanceDto"
}
}
}
},
"responses": {
"200": {
"description": "Instance updated (secret masked).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstanceView"
}
}
}
}
},
"tags": [
"integration"
]
},
"delete": {
"operationId": "IntegrationInstanceController_remove",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Instance deleted and its session scope torn down."
}
},
"tags": [
"integration"
]
}
},
"/api/integration/plugins/{pluginId}/instances/{instanceId}/regenerate-secret": {
"post": {
"operationId": "IntegrationInstanceController_regenerate",
"parameters": [
{
"name": "pluginId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
},
{
"name": "instanceId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Secret regenerated. The new plaintext secret is revealed once in this response; the verifyToken is also shown (unchanged).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InstanceView"
}
}
}
}
},
"tags": [
"integration"
]
}
},
"/api/search": {
"get": {
"operationId": "SearchController_search",
"parameters": [
{
"name": "q",
"required": true,
"in": "query",
"description": "Search term (required, non-empty)",
"schema": {
"type": "string"
}
},
{
"name": "sessionId",
"required": false,
"in": "query",
"description": "Restrict to a single session",
"schema": {
"type": "string"
}
},
{
"name": "chatId",
"required": false,
"in": "query",
"description": "Restrict to a single chat id",
"schema": {
"type": "string"
}
},
{
"name": "from",
"required": false,
"in": "query",
"description": "Sender filter",
"schema": {
"type": "string"
}
},
{
"name": "direction",
"required": false,
"in": "query",
"description": "incoming | outgoing",
"schema": {
"type": "string",
"enum": [
"incoming",
"outgoing"
]
}
},
{
"name": "type",
"required": false,
"in": "query",
"description": "Message type filter",
"schema": {
"type": "string"
}
},
{
"name": "dateFrom",
"required": false,
"in": "query",
"description": "Epoch-ms lower bound (inclusive)",
"schema": {
"type": "number"
}
},
{
"name": "dateTo",
"required": false,
"in": "query",
"description": "Epoch-ms upper bound (inclusive)",
"schema": {
"type": "number"
}
},
{
"name": "limit",
"required": false,
"in": "query",
"description": "Max hits to return",
"schema": {
"type": "number"
}
},
{
"name": "offset",
"required": false,
"in": "query",
"description": "Pagination offset",
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "Search results from the active provider"
},
"400": {
"description": "Empty or whitespace-only \"q\""
},
"501": {
"description": "No search provider configured"
}
},
"summary": "Search messages across sessions (active search provider)",
"tags": [
"search"
]
}
}
},
"info": {
"title": "OpenWA API",
"description": "Open Source WhatsApp API Gateway - Free, Self-Hosted HTTP API",
"version": "0.10.7",
"contact": {
"name": "OpenWA",
"url": "https://github.com/rmyndharis/OpenWA",
"email": "yudhi@rmyndharis.com"
}
},
"tags": [
{
"name": "sessions",
"description": "WhatsApp session management"
},
{
"name": "messages",
"description": "Send and manage messages"
},
{
"name": "webhooks",
"description": "Webhook configuration"
},
{
"name": "contacts",
"description": "Contact management"
},
{
"name": "groups",
"description": "Group management"
},
{
"name": "labels",
"description": "Label management (WhatsApp Business)"
},
{
"name": "channels",
"description": "Channel/Newsletter management"
},
{
"name": "catalog",
"description": "Product catalog (WhatsApp Business)"
},
{
"name": "status",
"description": "Status/Stories"
},
{
"name": "statistics",
"description": "Usage statistics"
},
{
"name": "templates",
"description": "Message templates"
},
{
"name": "plugins",
"description": "Plugin management"
},
{
"name": "settings",
"description": "Application settings"
},
{
"name": "infrastructure",
"description": "Infrastructure & datastore management"
},
{
"name": "integration",
"description": "Integration Fabric (provider webhooks & instances)"
},
{
"name": "auth",
"description": "API key management"
},
{
"name": "audit",
"description": "Audit log"
},
{
"name": "metrics",
"description": "Prometheus metrics"
},
{
"name": "health",
"description": "Health check endpoints"
}
],
"servers": [],
"components": {
"securitySchemes": {
"X-API-Key": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
}
},
"schemas": {
"CreateApiKeyDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Friendly name for the API key",
"example": "Production Bot"
},
"role": {
"type": "string",
"description": "Role/permission level",
"enum": [
"admin",
"operator",
"viewer"
],
"default": "operator"
},
"allowedIps": {
"description": "Allowed IP addresses (whitelist)",
"example": [
"192.168.1.1",
"10.0.0.0/8"
],
"type": "array",
"items": {
"type": "string"
}
},
"allowedSessions": {
"description": "Allowed session IDs this key can access",
"example": [
"session-uuid-1",
"session-uuid-2"
],
"type": "array",
"items": {
"type": "string"
}
},
"expiresAt": {
"type": "string",
"description": "Expiration date (ISO 8601)",
"example": "2027-12-31T23:59:59Z"
}
},
"required": [
"name"
]
},
"ApiKeyCreatedResponseDto": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"keyPrefix": {
"type": "string",
"description": "First 8 characters of the key (for identification)"
},
"role": {
"type": "string",
"enum": [
"admin",
"operator",
"viewer"
]
},
"allowedIps": {
"type": "array",
"items": {
"type": "string"
}
},
"allowedSessions": {
"type": "array",
"items": {
"type": "string"
}
},
"isActive": {
"type": "boolean"
},
"expiresAt": {
"format": "date-time",
"type": "string"
},
"lastUsedAt": {
"format": "date-time",
"type": "string"
},
"usageCount": {
"type": "number"
},
"createdAt": {
"format": "date-time",
"type": "string"
},
"apiKey": {
"type": "string",
"description": "Full API key (only shown once at creation)",
"example": "owa_k1_abc123..."
}
},
"required": [
"id",
"name",
"keyPrefix",
"role",
"isActive",
"usageCount",
"createdAt",
"apiKey"
]
},
"ApiKeyResponseDto": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"keyPrefix": {
"type": "string",
"description": "First 8 characters of the key (for identification)"
},
"role": {
"type": "string",
"enum": [
"admin",
"operator",
"viewer"
]
},
"allowedIps": {
"type": "array",
"items": {
"type": "string"
}
},
"allowedSessions": {
"type": "array",
"items": {
"type": "string"
}
},
"isActive": {
"type": "boolean"
},
"expiresAt": {
"format": "date-time",
"type": "string"
},
"lastUsedAt": {
"format": "date-time",
"type": "string"
},
"usageCount": {
"type": "number"
},
"createdAt": {
"format": "date-time",
"type": "string"
}
},
"required": [
"id",
"name",
"keyPrefix",
"role",
"isActive",
"usageCount",
"createdAt"
]
},
"UpdateApiKeyDto": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"role": {
"type": "string",
"enum": [
"admin",
"operator",
"viewer"
]
},
"allowedIps": {
"type": "array",
"items": {
"type": "string"
}
},
"allowedSessions": {
"type": "array",
"items": {
"type": "string"
}
},
"expiresAt": {
"type": "string"
}
}
},
"CreateSessionDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Unique name for the session (alphanumeric and hyphens only)",
"example": "my-bot",
"minLength": 3,
"maxLength": 50
},
"config": {
"type": "object",
"description": "Session configuration options. Set autoRejectCalls (boolean, default false) to automatically reject incoming calls — the call.received event is still emitted.",
"example": {
"autoReconnect": true
}
},
"proxyUrl": {
"type": "string",
"description": "Optional per-session egress proxy URL (http/https/socks4/socks5; credentialed form \"http://user:pass@host\" allowed). Must be a REAL, REACHABLE proxy — an unreachable value silently blocks the WhatsApp WebSocket (no QR is ever delivered) and the session start times out (~30s → 504 Gateway Timeout). Leave unset unless your network cannot reach WhatsApp directly."
},
"proxyType": {
"type": "string",
"description": "Proxy type",
"enum": [
"http",
"https",
"socks4",
"socks5"
],
"example": "http"
}
},
"required": [
"name"
]
},
"SessionResponseDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "sess_123e4567-e89b-12d3-a456-426614174000"
},
"name": {
"type": "string",
"example": "my-bot"
},
"status": {
"type": "string",
"enum": [
"created",
"initializing",
"qr_ready",
"authenticating",
"ready",
"disconnected",
"failed"
],
"example": "ready"
},
"phone": {
"type": "string",
"example": "628123456789",
"nullable": true
},
"pushName": {
"type": "string",
"example": "John Doe",
"nullable": true
},
"connectedAt": {
"type": "string",
"format": "date-time",
"example": "2025-02-02T10:00:00Z",
"nullable": true
},
"lastActive": {
"type": "string",
"format": "date-time",
"example": "2025-02-02T10:30:00Z",
"nullable": true
},
"createdAt": {
"format": "date-time",
"type": "string",
"example": "2025-02-02T09:00:00Z"
},
"updatedAt": {
"format": "date-time",
"type": "string",
"example": "2025-02-02T10:00:00Z"
},
"lastError": {
"type": "string",
"description": "Human-readable reason for the most recent terminal engine failure (only set when status is FAILED).",
"example": "Failed to launch the browser process: spawn /usr/bin/chromium ENOENT",
"nullable": true
}
},
"required": [
"id",
"name",
"status",
"createdAt",
"updatedAt"
]
},
"QRCodeResponseDto": {
"type": "object",
"properties": {
"qrCode": {
"type": "string",
"description": "QR code as data URL",
"example": "data:image/png;base64,..."
},
"status": {
"type": "string",
"enum": [
"created",
"initializing",
"qr_ready",
"authenticating",
"ready",
"disconnected",
"failed"
],
"example": "qr_ready"
}
},
"required": [
"qrCode",
"status"
]
},
"RequestPairingCodeDto": {
"type": "object",
"properties": {
"phoneNumber": {
"type": "string",
"description": "Phone number to link, digits only in international format (country code + number).",
"example": "628123456789"
}
},
"required": [
"phoneNumber"
]
},
"PairingCodeResponseDto": {
"type": "object",
"properties": {
"pairingCode": {
"type": "string",
"description": "The 8-character pairing code to enter in WhatsApp.",
"example": "ABCD1234"
},
"status": {
"type": "string",
"description": "Current session status.",
"example": "qr_ready"
}
},
"required": [
"pairingCode",
"status"
]
},
"MarkChatReadDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat ID in the active engine's native format (e.g. 1234567890@c.us on whatsapp-web.js)",
"example": "1234567890@c.us"
}
},
"required": [
"chatId"
]
},
"DeleteChatDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat ID in the active engine's native format (e.g. 1234567890-123@g.us on whatsapp-web.js)",
"example": "1234567890-123@g.us"
}
},
"required": [
"chatId"
]
},
"SendChatStateDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat ID, in the active engine's native format (e.g. 1234567890@c.us)",
"example": "1234567890@c.us"
},
"state": {
"type": "string",
"description": "Presence to send: 'typing' or 'recording' shows the indicator; 'paused' clears it",
"enum": [
"typing",
"recording",
"paused"
],
"example": "typing"
}
},
"required": [
"chatId",
"state"
]
},
"CreateWebhookDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Webhook URL to receive events",
"example": "https://your-server.com/webhook"
},
"events": {
"type": "array",
"description": "Event types to subscribe to. '*' subscribes to all events.",
"example": [
"message.received",
"session.status"
],
"minItems": 1,
"items": {
"type": "string",
"enum": [
"message.received",
"message.sent",
"message.ack",
"message.failed",
"message.revoked",
"message.reaction",
"message.edited",
"session.status",
"session.qr",
"session.authenticated",
"session.disconnected",
"session.reconnect_loop",
"group.join",
"group.leave",
"group.update",
"call.received",
"*"
]
}
},
"secret": {
"type": "string",
"description": "Secret key for HMAC signature verification",
"example": "your-secret-key"
},
"headers": {
"type": "object",
"description": "Custom headers to include in webhook requests",
"example": {
"X-Custom-Header": "value"
}
},
"filters": {
"type": "object",
"description": "Optional smart pre-filter. When set, every condition must match (AND) for the webhook to fire. Omit or null to fire on every subscribed event.",
"example": {
"conditions": [
{
"field": "sender",
"operator": "is",
"value": [
"1234567890@c.us"
]
},
{
"field": "body",
"operator": "contains",
"value": "invoice"
}
]
}
},
"retryCount": {
"type": "number",
"description": "Number of retry attempts on failure",
"example": 3,
"minimum": 0,
"maximum": 5
}
},
"required": [
"url"
]
},
"WebhookResponseDto": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"sessionId": {
"type": "string"
},
"url": {
"type": "string"
},
"events": {
"type": "array",
"items": {
"type": "string"
}
},
"filters": {
"type": "object",
"description": "Optional smart pre-filter. When set, every condition must match (AND) for the webhook to fire. Omit or null to fire on every subscribed event.",
"example": {
"conditions": [
{
"field": "sender",
"operator": "is",
"value": [
"1234567890@c.us"
]
},
{
"field": "body",
"operator": "contains",
"value": "invoice"
}
]
}
},
"active": {
"type": "boolean"
},
"retryCount": {
"type": "number"
},
"lastTriggeredAt": {
"type": "object"
},
"createdAt": {
"format": "date-time",
"type": "string"
},
"updatedAt": {
"format": "date-time",
"type": "string"
}
},
"required": [
"id",
"sessionId",
"url",
"events",
"active",
"retryCount",
"createdAt",
"updatedAt"
]
},
"UpdateWebhookDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Webhook URL"
},
"events": {
"type": "array",
"description": "Event types to subscribe to. '*' subscribes to all events.",
"minItems": 1,
"items": {
"type": "string",
"enum": [
"message.received",
"message.sent",
"message.ack",
"message.failed",
"message.revoked",
"message.reaction",
"message.edited",
"session.status",
"session.qr",
"session.authenticated",
"session.disconnected",
"session.reconnect_loop",
"group.join",
"group.leave",
"group.update",
"call.received",
"*"
]
}
},
"secret": {
"type": "string",
"description": "Secret key for HMAC signature"
},
"headers": {
"type": "object",
"description": "Custom headers"
},
"filters": {
"type": "object",
"description": "Optional smart pre-filter. When set, every condition must match (AND) for the webhook to fire. Omit or null to fire on every subscribed event.",
"example": {
"conditions": [
{
"field": "sender",
"operator": "is",
"value": [
"1234567890@c.us"
]
},
{
"field": "body",
"operator": "contains",
"value": "invoice"
}
]
}
},
"active": {
"type": "boolean",
"description": "Enable/disable webhook"
},
"retryCount": {
"type": "number",
"description": "Retry count"
}
}
},
"SendTextMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "WhatsApp chat ID (phone@c.us for individual, groupId@g.us for groups)",
"example": "628123456789@c.us"
},
"text": {
"type": "string",
"description": "Text message content",
"example": "Hello from OpenWA!",
"maxLength": 4096
},
"mentions": {
"description": "WIDs to @mention (e.g. [\"62811@c.us\"]). The text/caption must also contain the @<number> token.",
"example": [
"628123456789@c.us"
],
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"chatId",
"text"
]
},
"MessageResponseDto": {
"type": "object",
"properties": {
"messageId": {
"type": "string",
"description": "The message id, assigned when the gateway accepts the message for sending. A 201 here means the message was handed to the WhatsApp client — it does NOT confirm delivery. WhatsApp does not reject an unregistered recipient synchronously, so a message to a number that is not on WhatsApp still returns 201 with a valid messageId; whether it later delivers, stalls, or is reported as an error reaches you asynchronously, if at all. To confirm a number is on WhatsApp before sending, use GET /api/sessions/{sessionId}/contacts/check/{number}; track real delivery via the message `status` field (sent → delivered → read, or failed if WhatsApp reports an error for it). A message resting at `sent` is not diagnostic on its own: a registered recipient whose device has not come online since the send stays at `sent` too.",
"example": "true_628123456789@c.us_3EB0123456789"
},
"timestamp": {
"type": "number",
"description": "Unix timestamp (seconds) at which the gateway accepted the message for sending.",
"example": 1706868000
}
},
"required": [
"messageId",
"timestamp"
]
},
"SendTemplateMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "WhatsApp chat ID (phone@c.us for individual, groupId@g.us for groups)",
"example": "628123456789@c.us"
},
"templateId": {
"type": "string",
"description": "Template ID to render. Provide either templateId or templateName.",
"example": "b1c2d3e4-f5a6-7890-bcde-f01234567890"
},
"templateName": {
"type": "string",
"description": "Template name to render. Provide either templateId or templateName.",
"example": "order-confirmation"
},
"vars": {
"type": "object",
"description": "Variables substituted into {{placeholder}} tokens in the template",
"example": {
"customer": "Alice",
"orderId": "1234"
}
}
},
"required": [
"chatId"
]
},
"SendMediaMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "WhatsApp chat ID",
"example": "628123456789@c.us"
},
"url": {
"type": "string",
"description": "Media URL (http/https)",
"example": "https://example.com/image.jpg"
},
"base64": {
"type": "string",
"description": "Base64 encoded media data"
},
"mimetype": {
"type": "string",
"description": "Media MIME type (required when using base64)",
"example": "image/jpeg"
},
"filename": {
"type": "string",
"description": "Filename for the media",
"example": "image.jpg"
},
"caption": {
"type": "string",
"description": "Caption for the media",
"example": "Check out this image!",
"maxLength": 1024
},
"mentions": {
"description": "WIDs to @mention (e.g. [\"62811@c.us\"]). The text/caption must also contain the @<number> token.",
"example": [
"628123456789@c.us"
],
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"chatId"
]
},
"SendAudioMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "WhatsApp chat ID",
"example": "628123456789@c.us"
},
"url": {
"type": "string",
"description": "Media URL (http/https)",
"example": "https://example.com/image.jpg"
},
"base64": {
"type": "string",
"description": "Base64 encoded media data"
},
"mimetype": {
"type": "string",
"description": "Media MIME type (required when using base64)",
"example": "image/jpeg"
},
"filename": {
"type": "string",
"description": "Filename for the media",
"example": "image.jpg"
},
"caption": {
"type": "string",
"description": "Caption for the media",
"example": "Check out this image!",
"maxLength": 1024
},
"mentions": {
"description": "WIDs to @mention (e.g. [\"62811@c.us\"]). The text/caption must also contain the @<number> token.",
"example": [
"628123456789@c.us"
],
"type": "array",
"items": {
"type": "string"
}
},
"ptt": {
"type": "boolean",
"description": "Send as a WhatsApp voice note (PTT — mic bubble + waveform). Provide audio/ogg; codecs=opus bytes for reliable playback; when the mimetype is omitted it defaults to that for voice notes. Expects a JSON boolean. Default false = plain audio file. Only valid on send-audio."
}
},
"required": [
"chatId"
]
},
"SendLocationDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat ID (e.g. 628123456789@c.us)"
},
"latitude": {
"type": "number",
"example": -6.2088
},
"longitude": {
"type": "number",
"example": 106.8456
},
"description": {
"type": "string",
"maxLength": 1024
},
"address": {
"type": "string",
"maxLength": 1024
}
},
"required": [
"chatId",
"latitude",
"longitude"
]
},
"SendContactDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string"
},
"contactName": {
"type": "string",
"maxLength": 255
},
"contactNumber": {
"type": "string",
"maxLength": 30
}
},
"required": [
"chatId",
"contactName",
"contactNumber"
]
},
"SendPollDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat ID (e.g. 628123456789@c.us or 1203630000@g.us)"
},
"name": {
"type": "string",
"description": "Poll question / title",
"maxLength": 255,
"example": "Where should we meet?"
},
"options": {
"description": "Options to vote on (WhatsApp allows between 2 and 12)",
"example": [
"Park",
"Beach",
"Downtown"
],
"type": "array",
"items": {
"type": "string"
}
},
"allowMultipleAnswers": {
"type": "boolean",
"description": "Allow voters to pick several options (default single choice)"
}
},
"required": [
"chatId",
"name",
"options"
]
},
"ReplyMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string"
},
"quotedMessageId": {
"type": "string"
},
"text": {
"type": "string",
"maxLength": 4096
}
},
"required": [
"chatId",
"quotedMessageId",
"text"
]
},
"ForwardMessageDto": {
"type": "object",
"properties": {
"fromChatId": {
"type": "string"
},
"toChatId": {
"type": "string"
},
"messageId": {
"type": "string"
}
},
"required": [
"fromChatId",
"toChatId",
"messageId"
]
},
"ReactMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string"
},
"messageId": {
"type": "string"
},
"emoji": {
"type": "string",
"description": "Emoji to react with. Send an empty string to remove the reaction.",
"maxLength": 32
}
},
"required": [
"chatId",
"messageId",
"emoji"
]
},
"DeleteMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string"
},
"messageId": {
"type": "string"
},
"forEveryone": {
"type": "boolean",
"description": "Delete for everyone (default true)"
}
},
"required": [
"chatId",
"messageId"
]
},
"EditMessageDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string"
},
"messageId": {
"type": "string"
},
"body": {
"type": "string",
"description": "New text body for the message",
"maxLength": 4096
}
},
"required": [
"chatId",
"messageId",
"body"
]
},
"BulkMediaDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Media URL (http/https)"
},
"base64": {
"type": "string",
"description": "Base64-encoded media data"
},
"mimetype": {
"type": "string",
"description": "Media MIME type"
},
"filename": {
"type": "string",
"description": "Filename (documents only)"
},
"ptt": {
"type": "boolean",
"description": "Audio only: send as a WhatsApp voice note (PTT)"
}
}
},
"BulkMessageContentDto": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Text content for text messages",
"maxLength": 4096
},
"image": {
"description": "Image URL or base64",
"allOf": [
{
"$ref": "#/components/schemas/BulkMediaDto"
}
]
},
"video": {
"description": "Video URL or base64",
"allOf": [
{
"$ref": "#/components/schemas/BulkMediaDto"
}
]
},
"audio": {
"description": "Audio URL or base64",
"allOf": [
{
"$ref": "#/components/schemas/BulkMediaDto"
}
]
},
"document": {
"description": "Document URL or base64",
"allOf": [
{
"$ref": "#/components/schemas/BulkMediaDto"
}
]
},
"caption": {
"type": "string",
"description": "Caption for media messages",
"maxLength": 1024
}
}
},
"BulkMessageItemDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Recipient chat ID",
"example": "628123456789@c.us"
},
"type": {
"type": "string",
"description": "Message type",
"enum": [
"text",
"image",
"video",
"audio",
"document"
]
},
"content": {
"description": "Message content based on type",
"allOf": [
{
"$ref": "#/components/schemas/BulkMessageContentDto"
}
]
},
"variables": {
"type": "object",
"description": "Variables for template substitution"
}
},
"required": [
"chatId",
"type",
"content"
]
},
"BulkMessageOptionsDto": {
"type": "object",
"properties": {
"delayBetweenMessages": {
"type": "number",
"description": "Delay between messages in ms (min: 1000, default: 3000)",
"default": 3000
},
"randomizeDelay": {
"type": "boolean",
"description": "Add random 0-2s to delay",
"default": true
},
"stopOnError": {
"type": "boolean",
"description": "Stop batch on first error",
"default": false
}
}
},
"SendBulkMessageDto": {
"type": "object",
"properties": {
"batchId": {
"type": "string",
"description": "Custom batch ID (auto-generated if not provided)"
},
"messages": {
"description": "Array of messages (max 100 per request)",
"type": "array",
"items": {
"$ref": "#/components/schemas/BulkMessageItemDto"
}
},
"options": {
"description": "Batch processing options",
"allOf": [
{
"$ref": "#/components/schemas/BulkMessageOptionsDto"
}
]
}
},
"required": [
"messages"
]
},
"BulkMessageResponseDto": {
"type": "object",
"properties": {
"batchId": {
"type": "string"
},
"status": {
"type": "string"
},
"totalMessages": {
"type": "number"
},
"estimatedCompletionTime": {
"type": "string"
},
"statusUrl": {
"type": "string"
}
},
"required": [
"batchId",
"status",
"totalMessages",
"statusUrl"
]
},
"CreateTemplateDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Unique template name within the session",
"example": "order-confirmation",
"maxLength": 100
},
"body": {
"type": "string",
"description": "Template body with {{variable}} placeholders",
"example": "Hi {{customer}}, your order {{orderId}} has shipped.",
"maxLength": 4096
},
"header": {
"type": "string",
"description": "Optional header text, prepended to the rendered body",
"example": "OpenWA Store",
"maxLength": 1024
},
"footer": {
"type": "string",
"description": "Optional footer text, appended to the rendered body",
"example": "Reply STOP to unsubscribe.",
"maxLength": 1024
}
},
"required": [
"name",
"body"
]
},
"TemplateResponseDto": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"sessionId": {
"type": "string"
},
"name": {
"type": "string"
},
"body": {
"type": "string"
},
"header": {
"type": "string",
"nullable": true
},
"footer": {
"type": "string",
"nullable": true
},
"createdAt": {
"format": "date-time",
"type": "string"
},
"updatedAt": {
"format": "date-time",
"type": "string"
}
},
"required": [
"id",
"sessionId",
"name",
"body",
"createdAt",
"updatedAt"
]
},
"UpdateTemplateDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Template name",
"maxLength": 100
},
"body": {
"type": "string",
"description": "Template body with {{variable}} placeholders",
"maxLength": 4096
},
"header": {
"type": "string",
"description": "Optional header text",
"maxLength": 1024
},
"footer": {
"type": "string",
"description": "Optional footer text",
"maxLength": 1024
}
}
},
"DatabaseConfigDto": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"sqlite",
"postgres"
]
},
"builtIn": {
"type": "boolean"
},
"host": {
"type": "string"
},
"port": {
"type": "string"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"database": {
"type": "string"
},
"schema": {
"type": "string"
},
"poolSize": {
"type": "number"
},
"sslEnabled": {
"type": "boolean"
},
"sslRejectUnauthorized": {
"type": "boolean"
}
},
"required": [
"type"
]
},
"RedisConfigDto": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"builtIn": {
"type": "boolean"
},
"host": {
"type": "string"
},
"port": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"QueueConfigDto": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
}
},
"StorageConfigDto": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"local",
"s3"
]
},
"builtIn": {
"type": "boolean"
},
"localPath": {
"type": "string"
},
"s3Bucket": {
"type": "string"
},
"s3Region": {
"type": "string"
},
"s3AccessKey": {
"type": "string"
},
"s3SecretKey": {
"type": "string"
},
"s3Endpoint": {
"type": "string"
}
},
"required": [
"type"
]
},
"EngineConfigDto": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"headless": {
"type": "boolean"
},
"sessionDataPath": {
"type": "string"
},
"browserArgs": {
"type": "string"
}
}
},
"SaveConfigDto": {
"type": "object",
"properties": {
"database": {
"$ref": "#/components/schemas/DatabaseConfigDto"
},
"redis": {
"$ref": "#/components/schemas/RedisConfigDto"
},
"queue": {
"$ref": "#/components/schemas/QueueConfigDto"
},
"storage": {
"$ref": "#/components/schemas/StorageConfigDto"
},
"engine": {
"$ref": "#/components/schemas/EngineConfigDto"
}
}
},
"RestartDto": {
"type": "object",
"properties": {
"profiles": {
"type": "array",
"items": {
"type": "string"
}
},
"profilesToRemove": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"JoinGroupDto": {
"type": "object",
"properties": {
"inviteCode": {
"type": "string",
"description": "Group invite code (the token from a https://chat.whatsapp.com/<code> link)",
"maxLength": 128
}
},
"required": [
"inviteCode"
]
},
"GroupSettingsDto": {
"type": "object",
"properties": {
"announce": {
"type": "boolean",
"description": "Only admins can send messages (announce group)"
},
"locked": {
"type": "boolean",
"description": "Only admins can edit group info (locked group)"
},
"ephemeralSeconds": {
"type": "number",
"description": "Disappearing-messages timer in seconds; 0 disables. Known values: 86400 (24h), 604800 (7d), 7776000 (90d)",
"minimum": 0
}
}
},
"CreateGroupDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Group subject/name",
"maxLength": 100
},
"participants": {
"description": "Participant WhatsApp IDs (e.g. 628123456789@c.us)",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"name",
"participants"
]
},
"ParticipantsDto": {
"type": "object",
"properties": {
"participants": {
"description": "Participant WhatsApp IDs (e.g. 628123456789@c.us)",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"participants"
]
},
"GroupSubjectDto": {
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "New group subject/name",
"maxLength": 100
}
},
"required": [
"subject"
]
},
"GroupDescriptionDto": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "New group description (may be empty to clear it)",
"maxLength": 1024
}
},
"required": [
"description"
]
},
"SetProfileNameDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "New display name (WhatsApp limit: 25 characters)",
"maxLength": 25
}
},
"required": [
"name"
]
},
"SetProfileStatusDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "New about/status text (may be empty to clear it; WhatsApp limit: 139 characters)",
"maxLength": 139
}
},
"required": [
"status"
]
},
"SetProfilePictureDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Image URL (http/https)",
"example": "https://example.com/avatar.jpg"
},
"base64": {
"type": "string",
"description": "Base64 encoded image data"
},
"mimetype": {
"type": "string",
"description": "Image MIME type (required when using base64)",
"example": "image/jpeg"
}
}
},
"SendTextStatusDto": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Status text body.",
"example": "Out for delivery 📦",
"maxLength": 4096
},
"backgroundColor": {
"type": "string",
"description": "Background color (hex).",
"example": "#25D366"
},
"font": {
"type": "number",
"description": "Font family index (0–5).",
"example": 0,
"minimum": 0,
"maximum": 5
},
"recipients": {
"description": "Recipient JIDs (1–256). WhatsApp Status is not posted to a group — use @c.us or @lid individuals. Honored on the Baileys engine only: whatsapp-web.js ignores this allow-list and broadcasts to the account's status-privacy audience.",
"example": [
"628123456789@c.us"
],
"minItems": 1,
"maxItems": 256,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"text",
"recipients"
]
},
"StatusMediaInput": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Public http(s) URL of the media (server-fetched, SSRF-guarded).",
"example": "https://example.com/banner.jpg"
},
"base64": {
"type": "string",
"description": "Base64-encoded media. Requires mimetype.",
"example": "/9j/4AAQSkZJRg..."
},
"mimetype": {
"type": "string",
"description": "MIME type. Required when sending base64.",
"example": "image/jpeg"
}
}
},
"SendImageStatusDto": {
"type": "object",
"properties": {
"image": {
"description": "Image source (URL or base64).",
"allOf": [
{
"$ref": "#/components/schemas/StatusMediaInput"
}
]
},
"caption": {
"type": "string",
"description": "Optional caption.",
"example": "New drop!",
"maxLength": 1024
},
"recipients": {
"description": "Recipient JIDs (1–256), @c.us or @lid. Honored on the Baileys engine only: whatsapp-web.js ignores this allow-list and broadcasts to the account's status-privacy audience.",
"example": [
"628123456789@c.us"
],
"minItems": 1,
"maxItems": 256,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"image",
"recipients"
]
},
"SendVideoStatusDto": {
"type": "object",
"properties": {
"video": {
"description": "Video source (URL or base64).",
"allOf": [
{
"$ref": "#/components/schemas/StatusMediaInput"
}
]
},
"caption": {
"type": "string",
"description": "Optional caption.",
"example": "Demo",
"maxLength": 1024
},
"recipients": {
"description": "Recipient JIDs (1–256), @c.us or @lid. Honored on the Baileys engine only: whatsapp-web.js ignores this allow-list and broadcasts to the account's status-privacy audience.",
"example": [
"628123456789@c.us"
],
"minItems": 1,
"maxItems": 256,
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"video",
"recipients"
]
},
"SendProductDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat to send the product card to (@c.us or @g.us).",
"example": "628123456789@c.us"
},
"productId": {
"type": "string",
"description": "Catalog product id to send.",
"example": "product-42"
},
"body": {
"type": "string",
"description": "Optional body text accompanying the product card.",
"example": "Back in stock!"
}
},
"required": [
"chatId",
"productId"
]
},
"SendCatalogDto": {
"type": "object",
"properties": {
"chatId": {
"type": "string",
"description": "Chat to send the catalog to (@c.us or @g.us).",
"example": "628123456789@c.us"
},
"body": {
"type": "string",
"description": "Optional body text accompanying the catalog.",
"example": "Browse our full catalog"
}
},
"required": [
"chatId"
]
},
"InstallFromUrlDto": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "HTTP(S) URL of the plugin .zip to download and install"
}
},
"required": [
"url"
]
},
"PluginConfigDto": {
"type": "object",
"properties": {
"config": {
"type": "object",
"description": "Plugin configuration object"
}
},
"required": [
"config"
]
},
"PluginSessionsDto": {
"type": "object",
"properties": {
"sessions": {
"description": "Sessions to activate the plugin for; ['*'] = all numbers, [] = none",
"example": [
"*"
],
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"sessions"
]
},
"PluginDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Plugin ID"
},
"name": {
"type": "string",
"description": "Plugin name"
},
"version": {
"type": "string",
"description": "Plugin version"
},
"type": {
"type": "string",
"enum": [
"engine",
"storage",
"queue",
"auth",
"extension"
],
"description": "Plugin type"
},
"description": {
"type": "string",
"description": "Plugin description"
},
"author": {
"type": "string",
"description": "Plugin author"
},
"status": {
"type": "string",
"enum": [
"installed",
"enabled",
"disabled",
"error"
],
"description": "Plugin status"
},
"config": {
"type": "object",
"description": "Plugin configuration"
},
"builtIn": {
"type": "boolean",
"description": "Whether this is a built-in plugin"
},
"provides": {
"description": "Features provided by this plugin",
"type": "array",
"items": {
"type": "string"
}
},
"ingressCapable": {
"type": "boolean",
"description": "Whether this plugin can host provisioned ingress instances"
},
"sessionScoped": {
"type": "boolean",
"description": "Whether the plugin is scoped to specific sessions (false = global)"
},
"activeSessions": {
"description": "Sessions this plugin is activated for; ['*'] = all numbers",
"type": "array",
"items": {
"type": "string"
}
},
"configSchema": {
"type": "object",
"description": "Configuration schema"
},
"configUi": {
"type": "object",
"description": "Sandboxed-iframe config editor (entry HTML + optional height)"
},
"i18n": {
"type": "object",
"description": "Localized dashboard text (name/description/config titles) per locale code"
},
"sessionConfig": {
"type": "object",
"description": "Per-session config overrides, keyed by sessionId (secrets redacted)"
},
"loadedAt": {
"type": "string",
"description": "When the plugin was loaded"
},
"enabledAt": {
"type": "string",
"description": "When the plugin was enabled"
},
"error": {
"type": "string",
"description": "Error message if plugin is in error state"
}
},
"required": [
"id",
"name",
"version",
"type",
"status",
"config",
"builtIn",
"provides",
"ingressCapable",
"sessionScoped",
"activeSessions"
]
},
"CreateInstanceDto": {
"type": "object",
"properties": {
"instanceId": {
"type": "string",
"description": "Operator-chosen instance id (unique within the plugin). Namespaces the ingress URL and the instance secret.",
"example": "chatwoot-prod-1"
},
"sessionScope": {
"type": "string",
"description": "Session id the instance is scoped to. Omit for all sessions.",
"example": "8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a"
},
"verifyToken": {
"type": "string",
"description": "Token echoed back for the provider webhook verification handshake. Auto-generated when omitted.",
"example": "a1b2c3d4e5f6"
},
"secret": {
"type": "string",
"description": "Ingress HMAC secret shared with the provider. Omit to auto-generate a random 64-hex secret. Masked (****) on every read.",
"writeOnly": true,
"example": "super-secret-provider-webhook-key"
},
"config": {
"type": "object",
"description": "Per-instance config slice passed to the adapter (shape defined by the plugin).",
"example": {
"apiKey": "chatwoot-key",
"inboxId": 42
}
}
},
"required": [
"instanceId"
]
},
"IngressUrl": {
"type": "object",
"properties": {
"route": {
"type": "string",
"description": "Plugin-declared route segment the provider posts to."
},
"url": {
"type": "string",
"description": "Full ingress URL (BASE_URL + plugin/instance/route), or a relative path when BASE_URL is unset."
}
},
"required": [
"route",
"url"
]
},
"InstanceView": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Instance row id."
},
"pluginId": {
"type": "string",
"description": "Plugin id this instance belongs to."
},
"instanceId": {
"type": "string",
"description": "Operator-chosen instance id (unique within the plugin)."
},
"sessionScope": {
"type": "object",
"description": "Session id the instance is scoped to, or null for all sessions.",
"nullable": true
},
"secret": {
"type": "string",
"description": "Ingress HMAC secret. Masked ('***') on every read; plaintext returned only once on create/regenerate-secret."
},
"verifyToken": {
"type": "object",
"description": "Provider verify-token. Masked ('***') on reads when set; plaintext on create/regenerate-secret.",
"nullable": true
},
"config": {
"type": "object",
"description": "Per-instance config slice passed to the adapter, or null.",
"nullable": true
},
"enabled": {
"type": "boolean",
"description": "Whether ingress is accepted and dispatch is active."
},
"createdAt": {
"format": "date-time",
"type": "string",
"description": "Creation timestamp."
},
"updatedAt": {
"format": "date-time",
"type": "string",
"description": "Last update timestamp."
},
"ingressUrls": {
"description": "Ingress URLs the provider posts webhook deliveries to.",
"type": "array",
"items": {
"$ref": "#/components/schemas/IngressUrl"
}
}
},
"required": [
"id",
"pluginId",
"instanceId",
"secret",
"enabled",
"createdAt",
"updatedAt",
"ingressUrls"
]
},
"UpdateInstanceDto": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "Whether the instance is enabled (ingress accepted, dispatch active).",
"example": true
},
"sessionScope": {
"type": "string",
"description": "Session id the instance is scoped to. Omit for all sessions."
},
"config": {
"type": "object",
"description": "Per-instance config slice passed to the adapter."
}
}
}
}
},
"security": [
{
"X-API-Key": []
}
]
}