4ce4204b6c
CI / Lint (push) Failing after 2s
CI / Build (push) Has been skipped
SDK CI / PHP SDK (push) Failing after 1s
Split PHP SDK / PHP SDK tests (push) Failing after 1s
CI / Test (push) Failing after 1s
CI / Dashboard (push) Failing after 0s
SDK CI / JavaScript SDK (push) Failing after 0s
SDK CI / Python SDK (push) Failing after 2s
SDK CI / Java SDK (push) Failing after 1s
Split PHP SDK / Mirror sdk/php -> rmyndharis/openwa-php (push) Has been skipped
CI / Test (PostgreSQL migrations) (push) Failing after 7m47s
CI / Docker Build (push) Has been skipped
7210 lines
186 KiB
JSON
7210 lines
186 KiB
JSON
{
|
||
"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_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"
|
||
],
|
||
"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"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"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"
|
||
}
|
||
},
|
||
"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"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"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/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": {
|
||
"type": "string"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"responses": {
|
||
"200": {
|
||
"description": "Configuration saved"
|
||
}
|
||
},
|
||
"summary": "Save infrastructure configuration to .env file",
|
||
"tags": [
|
||
"infrastructure"
|
||
]
|
||
}
|
||
},
|
||
"/api/infra/restart": {
|
||
"post": {
|
||
"operationId": "InfraController_requestRestart",
|
||
"parameters": [],
|
||
"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/{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": {
|
||
"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": {
|
||
"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}/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 to the specified recipients."
|
||
}
|
||
},
|
||
"summary": "Post a text status (Baileys only)",
|
||
"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 to the specified recipients."
|
||
}
|
||
},
|
||
"summary": "Post an image status (Baileys only)",
|
||
"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 to the specified recipients."
|
||
}
|
||
},
|
||
"summary": "Post a video status (Baileys only)",
|
||
"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": "Business catalog metadata for the session."
|
||
}
|
||
},
|
||
"summary": "Get business catalog info",
|
||
"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": "Paginated list of catalog products."
|
||
}
|
||
},
|
||
"summary": "List catalog products",
|
||
"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": "The requested catalog product."
|
||
}
|
||
},
|
||
"summary": "Get a specific product",
|
||
"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": {
|
||
"201": {
|
||
"description": "Product message sent."
|
||
}
|
||
},
|
||
"summary": "Send a product message",
|
||
"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": {
|
||
"201": {
|
||
"description": "Catalog link sent."
|
||
}
|
||
},
|
||
"summary": "Send catalog link",
|
||
"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": "Dead-lettered ingress deliveries for the instance re-dispatched. Returns the count redriven."
|
||
}
|
||
},
|
||
"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.8.17",
|
||
"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",
|
||
"example": {
|
||
"autoReconnect": true
|
||
}
|
||
},
|
||
"proxyUrl": {
|
||
"type": "string",
|
||
"description": "Proxy URL for this session (e.g., http://user:pass@proxy.example.com:8080)",
|
||
"example": "http://proxy.example.com:8080"
|
||
},
|
||
"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",
|
||
"session.status",
|
||
"session.qr",
|
||
"session.authenticated",
|
||
"session.disconnected",
|
||
"group.join",
|
||
"group.leave",
|
||
"group.update",
|
||
"*"
|
||
]
|
||
}
|
||
},
|
||
"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",
|
||
"session.status",
|
||
"session.qr",
|
||
"session.authenticated",
|
||
"session.disconnected",
|
||
"group.join",
|
||
"group.leave",
|
||
"group.update",
|
||
"*"
|
||
]
|
||
}
|
||
},
|
||
"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",
|
||
"example": "true_628123456789@c.us_3EB0123456789"
|
||
},
|
||
"timestamp": {
|
||
"type": "number",
|
||
"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"
|
||
]
|
||
},
|
||
"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
|
||
}
|
||
}
|
||
},
|
||
"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"
|
||
]
|
||
},
|
||
"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.",
|
||
"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": "data:image/jpeg;base64,..."
|
||
},
|
||
"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.",
|
||
"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.",
|
||
"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": []
|
||
}
|
||
]
|
||
}
|