openapi: 3.0.0 info: title: DIGIGO description: "DIGIGO implements a multi user and multi device REST API for WhatsApp.\n\n

Authentication

Admin Setup:

You can manage users and do some tests by using the builtin dashboard [here](/dashboard).

Add a Sample User via API

Run this command to create a test user:
curl -X POST http://localhost:8080/admin/users \\ \n-H \"Authorization: $DIGIGO_ADMIN_TOKEN\" \\ \n-H \"Content-Type: application/json\" \\ \n-d '{\"name\": \"John\", \"token\": \"Z1234ABCCXD\"}'  
\n\n

Webhook Configuration

To receive WhatsApp messages:

Phone number format:

\n\n

Global Dispatcher Flags & API Echo

Configure tenant-level skips for the shared dispatcher via /session/globaltransports/config and toggle Info.IsFromAPI emission through /session/echo/api. Both flows are surfaced in the dashboard and Postman collection.

" version: "2.0.1" termsOfService: "" schemes: - http servers: - url: "/" description: Current host tags: - name: Admin description: Administrative operations for managing users and user accounts - name: Admin Global description: Global system configurations including RabbitMQ, S3, and webhook settings - name: Admin DLQ description: Dead Letter Queue management for failed event processing and retry operations - name: Admin Event Archive description: Event Archive management for viewing and managing all archived events (DLQ and Success). Monitor delivery metrics, replay failed events, and maintain archive hygiene. - name: Admin Monitoring description: Real-time event monitoring, SSE streaming, and telemetry insights for administrators - name: Admin License description: License management and information for monitoring subscription status and features - name: System description: System health monitoring, metrics, and application information - name: Webhook description: Webhook configuration and event subscription management - name: Session description: Session management, authentication, QR code generation, and connection handling - name: Session S3 description: Per-user S3 storage configuration for media delivery and retention - name: Session RabbitMQ description: Per-user RabbitMQ configuration for event publishing and queue management - name: Session Skips description: Per-user skip media download, groups, newsletters, broadcasts, own messages, and calls configuration - name: Session Global Transports description: Manage per-transport skip flags that control how the global dispatcher enriches events (webhook, RabbitMQ, SQS, Redis, WebSocket, and S3) - name: Session Echo description: Per-user echo settings for API messages - name: User description: User profile management, contacts, and account settings - name: User LID description: Link ID (LID) mapping and conversion between phone numbers and LIDs - name: Chat description: Chat operations including message retrieval, archiving, pinning, and muting - name: Send description: "Send messages in all formats (text, media, documents, polls, buttons, lists, etc.).\n\nAPI Echo Messages
When the global flag ECHO_API_MESSAGES_ENABLED is true and the per-session echo setting is enabled, every successful API send emits a synthetic Message event through your configured transports/webhook. These events include the Info.IsFromAPI: true marker so downstream consumers can distinguish API-originated traffic. This ensures API-sent messages pass through the same filters/media pipeline as user-originated messages.\n\nPer-Message Echo Control (EchoApi Field)
All send endpoints support an optional EchoApi boolean field that provides message-level control over echo behavior. When set to true, the message will emit an API echo event regardless of global (ECHO_API_MESSAGES_ENABLED) or per-session (echo_api_messages) settings. This allows selective tracking of specific API-sent messages without enabling echo for all messages. The field is completely optional and defaults to respecting the configured echo settings when omitted. Use cases include: tracking critical business messages, monitoring specific conversation flows, or debugging individual message delivery." - name: Label description: Chat labeling and organization features - name: Group description: Group management including creation, participant management, and group settings - name: Community description: Community and sub-group management, announcements, and join requests - name: Business description: Business profiles, bots, order messages, and business-specific features - name: Device description: Device management, platform detection, and linked device information - name: Privacy description: Privacy settings, blocklist management, and disappearing message configuration - name: Newsletter description: Newsletter/channel management, subscriptions, and newsletter messaging - name: Status description: Status/story posting in various formats (text, image, video, audio) - name: Call description: Call handling and rejection operations - name: Sync description: Synchronization and data consistency management paths: /session/echo/api: post: tags: - Session Echo summary: Enable or disable API message echo operationId: configureEchoApiMessages description: | Controls whether messages sent via this API should emit Message events through the standard transports/webhook pipeline. Behavior: - When enabled, after each successful send, the server emits a synthetic Message event flagged as API-sourced. - Event marker: The emitted event's Info structure includes IsFromAPI: true - The emitted event rides the same media/filters pipeline as regular messages. Requirements: - Global kill switch ECHO_API_MESSAGES_ENABLED must be true. - This endpoint toggles the per-session setting stored on the user. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/EchoAPISettingsRequest" responses: 200: description: Echo API messages configuration updated content: application/json: schema: $ref: "#/definitions/EchoAPISettingsResponse" 401: description: Unauthorized - user token required content: application/json: schema: example: { "error": "unauthorized" } 500: description: Internal server error content: application/json: schema: example: { "error": "failed to update echo api messages configuration", } get: tags: - Session Echo summary: Get API message echo configuration operationId: getEchoApiMessagesConfig description: | Retrieves whether API message echo is enabled for this session. Note: The global kill switch ECHO_API_MESSAGES_ENABLED must be true for echo events to be emitted even when the per-session flag is enabled. security: - ApiKeyAuth: [] responses: 200: description: Echo API messages configuration retrieved content: application/json: schema: $ref: "#/definitions/EchoAPISettingsResponse" 401: description: Unauthorized - user token required content: application/json: schema: example: { "error": "unauthorized" } 500: description: Internal server error content: application/json: schema: example: { "error": "failed to get echo api messages configuration" } /admin/users: get: tags: - Admin summary: List all users description: Retrieve a complete list of all DigiGO users with their full configuration including connection status, webhook settings, proxy configuration, S3 storage, RabbitMQ messaging, WhatsApp configuration, and event filtering preferences. security: - AdminAuth: [] responses: 200: description: A JSON array of user objects with complete configuration content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: array items: $ref: "#/definitions/User" success: type: boolean example: true example: { "code": 200, "data": [ { "connected": true, "loggedIn": true, "events": "All", "expiration": 0, "id": "bec45bb93cbd24cbec32941ec3c93a12", "jid": "5491155551122:12@s.whatsapp.net", "name": "Some User", "avatar_url": "https://example.com/avatar.jpg", "token": "d030sl9aDL39sl3075zz", "webhook": "https://some.domain/webhook", "qrcode": "", "skip_media_download": false, "skip_groups": false, "skip_newsletters": false, "skip_broadcasts": false, "skip_own_messages": false, "skip_calls": false, "call_reject_message": "Sorry, I cannot take calls at the moment.", "call_reject_type": "busy", "globalTransportSkips": { "skipGlobalWebhook": false, "skipGlobalRabbitMQ": false, "skipGlobalSQS": false, "skipGlobalRedis": false, "skipGlobalWebSocket": false, "skipGlobalS3": false, }, "isFromAPI": false, "proxy_config": { "enabled": false, "proxy_url": "" }, "s3_config": { "enabled": false }, "rabbitmq_config": { "enabled": false }, "whatsapp_config": { "wa_platform": "WEB", "wa_release_channel": "RELEASE", }, "echo_api_messages": false, }, ], "success": true, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "problem accessing DB", "success": false, } post: tags: - Admin summary: Create a new DigiGO user account description: Create a new DigiGO user account with complete configuration options including webhook URL, proxy settings, S3 storage configuration, RabbitMQ messaging setup, WhatsApp client configuration, and event filtering settings. The user will receive a unique ID and authentication token upon successful creation. All configuration options are optional and will use sensible defaults if not provided. Admin authentication required. `s3Config` accepts both `snake_case` and `camelCase` keys for compatibility. security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CreateUser" responses: 201: description: User created content: application/json: schema: $ref: "#/definitions/User" example: code: 201 data: id: "5663e0c52063ec35d0ba45f7c2011c06" name: "John Doe" token: "1234ABCD" echoApiMessages: false skipMediaDownload: false skipGroups: false skipNewsletters: false skipBroadcasts: false skipOwnMessages: false globalTransportSkips: skipGlobalWebhook: false skipGlobalRabbitMQ: false skipGlobalSQS: false skipGlobalRedis: false skipGlobalWebSocket: false skipGlobalS3: false isFromAPI: false skipCalls: false callRejectMessage: "Sorry, I cannot take calls at the moment." callRejectType: "busy" webhook: "https://webhook.site/1234567890" events: "All" proxyConfig: enabled: true proxyURL: "https://serverproxy.com:9080" s3Config: enabled: true endpoint: "https://s3.amazonaws.com" region: "us-east-1" bucket: "my-bucket" access_key: "***" secret_key: "***" path_style: true public_url: "https://s3.amazonaws.com" media_delivery: "both" retention_days: 30 disable_acl: true rabbitmqConfig: enabled: true url: "amqp://guest:guest@localhost:5672/" events: "All" exchange: "whatsapp.events" exchange_type: "topic" queue: "whatsapp.user.{user_id}" queue_type: "classic" routing_key: "whatsapp.{event_type}" durable: true auto_delete: false exclusive: false no_wait: false delivery_mode: 2 dead_letter_exchange: "dlx.whatsapp" dead_letter_routing_key: "dlq.events" message_ttl: 86400000 max_length: 100000 max_length_bytes: 104857600 queue_arguments: { "x-overflow": "reject-publish" } exchange_arguments: {} whatsappConfig: waVersion: "2.3000.1026436087" waPlatform: "WEB" waReleaseChannel: "RELEASE" waWebSubPlatform: "WEB_BROWSER" waOsName: "Mac OS 10" waOsVersion: "10.15.7" waDeviceName: "Desktop" waManufacturer: "Apple" waDeviceBoard: "" waLocaleLanguage: "en" waLocaleCountry: "US" waMcc: "000" waMnc: "000" waConnectType: "WIFI_UNKNOWN" waPlatformType: "DESKTOP" /admin/instances/status: get: tags: - Admin summary: List instance connection status description: | Retrieve a lightweight paginated view of instance connection health using runtime state when available and database fallback when no in-memory client is present. Each entry includes the current QR code (base64 PNG and raw text) for unpaired instances. QR code fields are only populated when the instance is not connected or not logged in. security: - AdminAuth: [] parameters: - in: query name: limit schema: type: integer default: 200 minimum: 1 maximum: 1000 description: Number of instances per page (default 200, max 1000) - in: query name: offset schema: type: integer default: 0 minimum: 0 description: Pagination offset - in: query name: ids schema: type: string description: Optional comma-separated list of instance IDs for selective lookup - in: query name: include_total schema: type: boolean default: false description: When true, includes total row count in pagination metadata responses: 200: description: Paginated status list content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: array items: type: object properties: id: type: string name: type: string jid: type: string qrcode: type: string description: "Base64 PNG QR code for pairing (empty when connected and logged in)" qrcode_text: type: string description: "Raw QR code text string for pairing (empty when connected and logged in)" connected: type: boolean loggedIn: type: boolean hasClient: type: boolean connectionHealth: type: string enum: [ "connected", "connected_not_logged", "disconnected", "no_client", ] lastSuccessfulConnect: type: integer format: int64 autoReconnectErrors: type: integer enableAutoReconnect: type: boolean source: type: string enum: ["runtime", "database"] timestamp: type: string format: date-time pagination: type: object properties: limit: type: integer offset: type: integer has_more: type: boolean next_offset: type: integer nullable: true total: type: integer success: type: boolean example: true example: code: 200 data: - id: "4721ca1031bc81b888efc7f407e455ad" name: "teste-api-com-s3" jid: "5511999999999@s.whatsapp.net" qrcode: "" qrcode_text: "" connected: true loggedIn: true hasClient: true connectionHealth: "connected" lastSuccessfulConnect: 1740248400 autoReconnectErrors: 0 enableAutoReconnect: false source: "runtime" timestamp: "2026-02-22T15:05:00Z" pagination: limit: 200 offset: 0 has_more: false next_offset: null success: true 400: description: Invalid pagination/filter parameter content: application/json: schema: example: { "code": 400, "error": "invalid limit parameter", "success": false, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "database error", "success": false } /admin/users/{id}: get: tags: - Admin summary: Get specific user by ID description: Retrieve detailed information about a specific DigiGO user by their unique ID, including complete configuration, connection status, webhook settings, proxy configuration, S3 storage, RabbitMQ messaging, WhatsApp configuration, and event filtering preferences. security: - AdminAuth: [] parameters: - name: id in: path required: true description: Unique ID of the user to retrieve schema: type: string example: 4e4942c7dee1deef99ab8fd9f7350de5 responses: 200: description: User details retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: array items: $ref: "#/definitions/User" description: "Array containing the single user object" success: type: boolean example: true example: { "code": 200, "data": [ { "connected": true, "loggedIn": true, "events": "All", "expiration": 0, "id": "4e4942c7dee1deef99ab8fd9f7350de5", "jid": "5491155551122:12@s.whatsapp.net", "name": "John Doe", "avatar_url": "https://example.com/avatar.jpg", "token": "1234ABCD", "webhook": "https://webhook.site/1234567890", "qrcode": "", "skip_media_download": false, "skip_groups": false, "skip_newsletters": false, "skip_broadcasts": false, "skip_own_messages": false, "skip_calls": false, "call_reject_message": "Sorry, I cannot take calls at the moment.", "call_reject_type": "busy", "globalTransportSkips": { "skipGlobalWebhook": false, "skipGlobalRabbitMQ": false, "skipGlobalSQS": false, "skipGlobalRedis": false, "skipGlobalWebSocket": false, "skipGlobalS3": false, }, "isFromAPI": false, "proxy_config": { "enabled": true, "proxy_url": "https://serverproxy.com:9080", }, "s3_config": { "enabled": true, "endpoint": "https://s3.amazonaws.com", "region": "us-east-1", "bucket": "my-bucket", }, "rabbitmq_config": { "enabled": true, "url": "amqp://guest:guest@localhost:5672/", "exchange": "whatsapp.events", }, "whatsapp_config": { "wa_platform": "WEB", "wa_release_channel": "RELEASE", "wa_web_sub_platform": "WEB_BROWSER", }, "echo_api_messages": false, }, ], "success": true, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 404: description: User not found content: application/json: schema: example: { "code": 404, "error": "user not found", "success": false } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "problem accessing DB", "success": false, } delete: tags: - Admin summary: Delete a user from DB description: Deletes a user by their ID. security: - AdminAuth: [] parameters: - name: id in: path required: true description: ID of the user to delete schema: type: string example: 4e4942c7dee1deef99ab8fd9f7350de5 responses: 200: description: User deleted content: application/json: schema: example: { "code": 200, "data": { "id": "6b927654cada7635a4586bf8fad260a3" }, "details": "User deleted successfully", "success": true, } /admin/users/{id}/full: delete: tags: - Admin summary: Delete a user from DB, S3, RabbitMQ, logout and disconnect from whatsapp and clear it up from memory description: Deletes a user by their ID, including login out, disconnect and memory cleanup Also removes all user files from S3 and RabbitMQ. security: - AdminAuth: [] parameters: - name: id in: path required: true description: ID of the user to delete schema: type: string example: 4e4942c7dee1deef99ab8fd9f7350de5 responses: 200: description: User deleted content: application/json: schema: example: { "code": 200, "data": { "id": "4e4942c7dee1deef99ab8fd9f7350de5", "jid": "", "name": "mariano", }, "details": "User instance removed completely", "success": true, } /admin/license/info: get: tags: - Admin License summary: Get license information description: | Retrieve complete license information including validation status, expiration date, features, and grace period details. **Status Types**: - `active`: License valid and active - `expiring_soon`: License expires within 7 days (renewal recommended) - `grace_period`: License in grace period after expiration (limited time to renew) - `expired`: License expired (limited functionality) **Plan Types**: - `BASIC`: Basic features and standard support - `PRO`: Advanced features and priority support - `ENTERPRISE`: Full features, 24/7 support, and SLA guarantees **Authentication**: Requires admin token in Authorization header security: - AdminAuth: [] responses: 200: description: License information retrieved successfully content: application/json: schema: type: object required: - valid - installation_id - customer_id - installation_name - plan_type - expires_at - max_instances - license_key - instance_id - last_validation - days_until_expiry - is_in_grace_period - status - status_message - features - support_email - documentation_url properties: valid: type: boolean description: Whether the license is currently valid example: true installation_id: type: string description: Unique installation identifier example: "inst_1234567890abcdef" customer_id: type: string description: Customer account identifier example: "cust_abcdef1234567890" installation_name: type: string description: Human-readable installation name example: "Production Server - São Paulo" plan_type: type: string description: Current subscription plan enum: [BASIC, PRO, ENTERPRISE] example: "ENTERPRISE" expires_at: type: string format: date-time description: License expiration date and time (UTC) example: "2025-12-31T23:59:59Z" max_instances: type: integer description: Maximum number of concurrent instances allowed example: 10 license_key: type: string description: Complete license key (frontend controls visibility via toggle) example: "ZUCKZAP-ENT-2024-ABCD1234-EFGH5678-IJKL9012" instance_id: type: string description: Current running instance identifier example: "digigo-prod-01" last_validation: type: string format: date-time description: Timestamp of last successful license validation example: "2025-10-31T12:00:00Z" days_until_expiry: type: integer description: Number of days remaining until license expires (negative if expired) example: 61 is_in_grace_period: type: boolean description: Whether license is currently in grace period example: false grace_period_end: type: string format: date-time description: Grace period end date (only present when is_in_grace_period is true) example: "2025-11-07T23:59:59Z" status: type: string description: Current license status enum: [active, expiring_soon, grace_period, expired] example: "active" status_message: type: string description: Human-readable status message example: "Licença ativa e válida" features: type: array description: List of features available in current plan items: type: string example: - "API RESTful completa" - "Suporte a múltiplas instâncias" - "Eventos em tempo real" - "Suporte 24/7" - "SLA garantido" - "Botões interativos" support_email: type: string format: email description: Support contact email example: "suporte@setupautomatizado.com.br" documentation_url: type: string format: uri description: Documentation URL example: "https://github.com/digitalsac-io/digigo" example: { "valid": true, "installation_id": "inst_1234567890abcdef", "customer_id": "cust_abcdef1234567890", "installation_name": "Production Server - São Paulo", "plan_type": "ENTERPRISE", "expires_at": "2025-12-31T23:59:59Z", "max_instances": 10, "license_key": "ZUCKZAP-ENT-2024-ABCD1234-EFGH5678-IJKL9012", "instance_id": "digigo-prod-01", "last_validation": "2025-10-31T12:00:00Z", "days_until_expiry": 61, "is_in_grace_period": false, "status": "active", "status_message": "Licença ativa e válida", "features": [ "API RESTful completa", "Suporte a múltiplas instâncias", "Eventos em tempo real", "Suporte prioritário", "Integrações avançadas", "Suporte 24/7", "SLA garantido", "Botões interativos", ], "support_email": "suporte@setupautomatizado.com.br", "documentation_url": "https://github.com/digitalsac-io/digigo", } 401: description: Unauthorized - Admin token required content: application/json: schema: type: object properties: success: type: boolean example: false error: type: string example: "unauthorized - admin token required" code: type: integer example: 401 503: description: Service unavailable - License validator not initialized or cache unavailable content: application/json: schema: type: object properties: success: type: boolean example: false error: type: string example: "License information not available" code: type: integer example: 503 /newsletter/list: get: tags: - Newsletter summary: List subscribed newsletters description: Get complete list of subscribed newsletters with metadata security: - ApiKeyAuth: [] responses: 200: description: Newsletter list retrieved successfully content: application/json: schema: example: { "Newsletter": [ { "id": "1203631448483540@newsletter", "state": { "type": "active" }, "thread_metadata": { "creation_time": "1688746895", "description": { "id": "1689653839450668", "text": "WhatsApp's official channel", "update_time": "1689653839450668", }, "invite": "0029Va4K0PZ5a245NkngBA2M", "name": { "id": "1688746895480511", "text": "WhatsApp", "update_time": "1688746895480511", }, "subscribers_count": "1000000", "verification": "verified", }, "viewer_metadata": { "mute": "off", "role": "subscriber" }, }, ], } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /newsletter/create: post: tags: - Newsletter summary: Create new newsletter/channel description: Create a new WhatsApp newsletter/channel with optional picture (supports base64 data URLs and HTTP(S) URLs) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - name properties: name: type: string description: Newsletter name (automatically truncated to 25 characters) maxLength: 25 example: "My Newsletter" description: type: string description: Newsletter description (optional) example: "A newsletter about interesting topics" picture: type: string description: Base64 data URL (data:image/jpeg;base64,...) or HTTP(S) URL for newsletter picture. Supported formats JPEG, PNG, GIF, WebP example: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." responses: 200: description: Newsletter created successfully content: application/json: schema: type: object properties: success: type: boolean jid: type: string name: type: string message: type: string example: { "success": true, "jid": "120363025246817665@newsletter", "name": "My Newsletter", "message": "Newsletter created successfully", } 400: description: Bad request - validation error content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": false, "message": "name is required" } 500: description: Internal server error - no session content: application/json: schema: type: string example: "no session" /newsletter/subscribed: get: tags: - Newsletter summary: Get subscribed newsletters description: List all newsletters that the user is subscribed to with structured information security: - ApiKeyAuth: [] responses: 200: description: Subscribed newsletters retrieved successfully content: application/json: schema: type: object properties: success: type: boolean newsletters: type: array items: type: object properties: jid: type: string name: type: string description: type: string subscribers: type: integer muted: type: boolean invite_code: type: string example: { "success": true, "newsletters": [ { "jid": "120363025246817665@newsletter", "name": "Tech News", "description": "Latest tech updates", "subscribers": 1500, "muted": false, "invite_code": "ABC123XYZ", }, ], } 500: description: Internal server error content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": false, "message": "no session" } /newsletter/info: post: tags: - Newsletter summary: Get newsletter information description: Get detailed information about a specific newsletter by JID security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID (format 120363025246817665@newsletter) example: "120363025246817665@newsletter" responses: 200: description: Newsletter information retrieved successfully content: application/json: schema: type: object properties: jid: type: string name: type: string description: type: string subscribers: type: integer invite_code: type: string muted: type: boolean role: type: string example: { "jid": "120363025246817665@newsletter", "name": "Tech News", "description": "Latest technology updates", "subscribers": 1500, "invite_code": "ABC123XYZ", "muted": false, "role": "subscriber", } 400: description: Bad request - invalid newsletter ID content: application/json: schema: type: string example: "invalid newsletter ID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/send: post: tags: - Newsletter summary: Send message to newsletter description: Send text, image, video, document, or audio message to a newsletter. Media supports both base64 data URLs and HTTP(S) URLs. Audio messages are sent as voice notes (PTT=true) for newsletters. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" message: type: string description: Text message content (for text messages) example: "Hello subscribers!" image: type: string description: Base64 data URL (data:image/jpeg;base64,...) or HTTP(S) URL for image example: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." video: type: string description: Base64 data URL (data:video/mp4;base64,...) or HTTP(S) URL for video example: "https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4" document: type: string description: Base64 data URL (data:application/pdf;base64,...) or HTTP(S) URL for document example: "data:application/pdf;base64,JVBERi0xLjQKJcfs..." audio: type: string description: Base64 data URL (data:audio/ogg;base64,...) or HTTP(S) URL for audio (automatically sent as voice note PTT=true for newsletters) example: "data:audio/ogg;base64,T2dnUwACAAAAAAAAAAA..." caption: type: string description: Caption for media messages (image, video) example: "Check this out!" filename: type: string description: Filename for document messages (defaults to 'document' if not provided) example: "document.pdf" oneOf: - required: ["message"] - required: ["image"] - required: ["video"] - required: ["document"] - required: ["audio"] responses: 200: description: Message sent successfully content: application/json: schema: type: object properties: success: type: boolean id: type: string timestamp: type: integer format: int64 example: { "success": true, "id": "3EB0C767D26A1D74", "timestamp": 1640995200, } 400: description: Bad request - invalid input or no content content: application/json: schema: type: string example: "no message content provided" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/follow: post: tags: - Newsletter summary: Subscribe to newsletter description: Subscribe to a newsletter using its JID security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID to subscribe to example: "120363025246817665@newsletter" responses: 200: description: Successfully subscribed to newsletter content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Subscribed successfully" } 400: description: Bad request - invalid newsletter ID content: application/json: schema: type: string example: "invalid newsletter ID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/follow-invite: post: tags: - Newsletter summary: Subscribe via invite code description: Subscribe to a newsletter using an invite code security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - invite_code properties: invite_code: type: string description: Newsletter invite code example: "ABC123XYZ" responses: 200: description: Successfully subscribed via invite code content: application/json: schema: type: object properties: success: type: boolean message: type: string jid: type: string example: { "success": true, "message": "Subscribed successfully", "jid": "120363025246817665@newsletter", } 500: description: Internal server error content: application/json: schema: type: string example: "error getting info" /newsletter/unfollow: post: tags: - Newsletter summary: Unsubscribe from newsletter description: Unsubscribe from a newsletter using its JID security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID to unsubscribe from example: "120363025246817665@newsletter" responses: 200: description: Successfully unsubscribed from newsletter content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Unsubscribed successfully" } 400: description: Bad request - invalid newsletter ID content: application/json: schema: type: string example: "invalid newsletter ID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/unfollow-invite: post: tags: - Newsletter summary: Unsubscribe via invite code description: Unsubscribe from a newsletter using an invite code security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - invite_code properties: invite_code: type: string description: Newsletter invite code example: "ABC123XYZ" responses: 200: description: Successfully unsubscribed via invite code content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Unsubscribed successfully" } 500: description: Internal server error content: application/json: schema: type: string example: "error getting info" /newsletter/mute: post: tags: - Newsletter summary: Mute/unmute newsletter notifications description: Toggle mute status for newsletter notifications security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid - mute properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" mute: type: boolean description: True to mute notifications, false to enable example: true responses: 200: description: Mute status changed successfully content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Notifications muted successfully", } 400: description: Bad request - invalid JID content: application/json: schema: type: string example: "invalid JID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/messages: post: tags: - Newsletter summary: Get newsletter messages description: Retrieve messages from a newsletter with pagination support security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" count: type: integer description: Number of messages to retrieve (default 25) default: 25 example: 25 before: type: integer description: Server ID to get messages before this ID (for pagination) example: 12345 responses: 200: description: Newsletter messages retrieved successfully content: application/json: schema: type: object properties: success: type: boolean messages: type: array items: type: object properties: id: type: string server_id: type: integer type: type: string timestamp: type: integer format: int64 text: type: string caption: type: string views_count: type: integer reaction_counts: type: object media: type: object example: { "success": true, "messages": [ { "id": "3EB0C767D26A1D74", "server_id": 12345, "type": "text", "timestamp": 1640995200, "text": "Hello world!", "views_count": 150, "reaction_counts": { "👍": 25, "❤️": 10 }, }, ], } 400: description: Bad request - invalid newsletter ID content: application/json: schema: type: string example: "invalid newsletter ID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/reaction: post: tags: - Newsletter summary: Send reaction to newsletter message description: Send an emoji reaction to a specific newsletter message security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid - server_id - reaction properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" server_id: type: integer description: Server ID of the message to react to example: 12345 reaction: type: string description: Emoji reaction (empty string to remove reaction) example: "👍" responses: 200: description: Reaction sent successfully content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Reaction sent successfully" } 400: description: Bad request - invalid JID content: application/json: schema: type: string example: "invalid JID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/mark-viewed: post: tags: - Newsletter summary: Mark newsletter messages as viewed description: Mark specific newsletter messages as viewed to update read status security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid - server_ids properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" server_ids: type: array items: type: integer description: Array of server IDs to mark as viewed example: [12345, 12346, 12347] responses: 200: description: Messages marked as viewed successfully content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Messages marked as viewed" } 400: description: Bad request - invalid JID content: application/json: schema: type: string example: "invalid JID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/subscribe-live-updates: post: tags: - Newsletter summary: Subscribe to live updates description: Subscribe to real-time updates for a newsletter (30 second timeout) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" responses: 200: description: Successfully subscribed to live updates content: application/json: schema: type: object properties: success: type: boolean duration: type: number format: float message: type: string example: { "success": true, "duration": 3600.0, "message": "Subscribed to live updates", } 400: description: Bad request - invalid JID content: application/json: schema: type: string example: "invalid JID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/message-updates: post: tags: - Newsletter summary: Get newsletter message updates description: Get updates for newsletter messages with filtering options security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - jid properties: jid: type: string description: Newsletter JID example: "120363025246817665@newsletter" count: type: integer description: Number of updates to retrieve (optional) example: 25 since: type: integer format: int64 description: Unix timestamp to get updates since (optional) example: 1640995200 after: type: integer description: Server ID to get updates after (optional) example: 12345 responses: 200: description: Message updates retrieved successfully content: application/json: schema: type: object properties: success: type: boolean updates: type: array items: type: object properties: id: type: string server_id: type: integer type: type: string timestamp: type: integer format: int64 views_count: type: integer reaction_counts: type: object text: type: string caption: type: string media: type: object example: { "success": true, "updates": [ { "id": "3EB0C767D26A1D74", "server_id": 12346, "type": "text", "timestamp": 1640995300, "text": "Updated message", "views_count": 200, "reaction_counts": { "👍": 30, "❤️": 15 }, }, ], } 400: description: Bad request - invalid JID content: application/json: schema: type: string example: "invalid JID" 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/accept-tos: post: tags: - Newsletter summary: Accept Terms of Service description: Accept WhatsApp Terms of Service notice required for newsletter creation security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: notice_id: type: string description: Terms of Service notice ID (default "20601218" for newsletter creation) default: "20601218" example: "20601218" stage: type: string description: TOS stage (default "5" for newsletter creation) default: "5" example: "5" responses: 200: description: Terms of service accepted successfully content: application/json: schema: type: object properties: success: type: boolean message: type: string example: { "success": true, "message": "Terms of service accepted" } 500: description: Internal server error content: application/json: schema: type: string example: "no session" /newsletter/admin-invite: post: tags: - Newsletter summary: Send Newsletter Admin Invite description: Send an admin invitation for a newsletter to a phone number with image and custom message security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - newsletter_jid - image - caption - name properties: phone: type: string description: Recipient phone number (with country code, no + prefix) example: "5491155553934" newsletter_jid: type: string description: Newsletter JID to invite admin for example: "120363025246817665@newsletter" image: type: string description: Base64 data URL or HTTP(S) URL for invitation image example: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." caption: type: string description: Invitation message text example: "You're invited to be an admin of our newsletter!" name: type: string description: Newsletter/invite name example: "Tech Newsletter Admin Invite" responses: 200: description: Admin invite sent successfully content: application/json: schema: example: { "success": true, "id": "3EB0C767D26A1D74", "timestamp": 1640995200, "recipient": "5491155553934", "newsletter_jid": "120363025246817665@newsletter", "invite_name": "Tech Newsletter Admin Invite", "expires_at": 1641600000, "message": "Newsletter admin invite sent successfully", } 400: description: Bad request - invalid input content: application/json: schema: example: { "error": "phone, newsletter_jid, image, caption and name are required", } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /health: get: tags: - System summary: Health check description: Returns system health status for monitoring purposes responses: 200: description: System is healthy content: application/json: schema: type: object required: - code - data - success - status - version - uptime - timestamp - metrics - environment properties: code: type: integer format: int32 description: HTTP status code mirrored from the response example: 200 data: type: string description: Legacy health message (kept for backward compatibility) example: OK success: type: boolean description: Indicates the health endpoint responded successfully example: true status: type: string description: Aggregated health status derived from dependency checks enum: [healthy, degraded, unhealthy] example: healthy version: type: string description: Running build version identifier example: 3.0.0 uptime: type: integer format: int64 description: Uptime in seconds since the process started example: 86400 timestamp: type: string format: date-time description: Moment the health snapshot was generated (UTC) example: 2024-01-01T12:00:00Z metrics: type: object required: [goroutines, go_version, cpu_count, go_max_procs] properties: goroutines: type: integer example: 42 go_version: type: string example: go1.21.5 cpu_count: type: integer example: 8 go_max_procs: type: integer example: 8 environment: type: object required: [containerized] properties: containerized: type: boolean example: false hostname: type: string nullable: true example: digigo-01 app_env: type: string nullable: true example: production app_region: type: string nullable: true example: us-east-1 build: type: object nullable: true properties: commit: type: string description: Deployed git commit hash (if available) example: a1b2c3d4 services: type: object nullable: true additionalProperties: type: object properties: status: type: string description: Dependency health status example: up latency_ms: type: number format: float example: 12.5 open_connections: type: integer example: 10 in_use: type: integer example: 2 idle: type: integer example: 8 driver: type: string example: postgres error: type: string nullable: true example: "" example: { "code": 200, "data": "OK", "success": true, "status": "healthy", "version": "3.0.0", "uptime": 86400, "timestamp": "2024-01-01T12:00:00Z", "metrics": { "goroutines": 42, "go_version": "go1.21.5", "cpu_count": 8, "go_max_procs": 8, }, "environment": { "containerized": false, "hostname": "digigo-01", "app_env": "production", "app_region": "us-east-1", }, "build": { "commit": "a1b2c3d4" }, "services": { "database": { "status": "up", "latency_ms": 12.5, "open_connections": 10, "in_use": 2, "idle": 8, "driver": "postgres", }, }, } 503: description: System is unhealthy content: application/json: schema: type: object required: - code - data - success - status - version - uptime - timestamp - metrics - environment properties: code: type: integer format: int32 example: 503 data: type: string example: ERROR success: type: boolean example: true status: type: string enum: [healthy, degraded, unhealthy] example: unhealthy version: type: string example: 3.0.0 uptime: type: integer format: int64 example: 86400 timestamp: type: string format: date-time example: 2024-01-01T12:00:00Z metrics: type: object required: [goroutines, go_version, cpu_count, go_max_procs] properties: goroutines: type: integer example: 42 go_version: type: string example: go1.21.5 cpu_count: type: integer example: 8 go_max_procs: type: integer example: 8 environment: type: object required: [containerized] properties: containerized: type: boolean example: false hostname: type: string nullable: true example: digigo-01 app_env: type: string nullable: true example: production app_region: type: string nullable: true example: us-east-1 build: type: object nullable: true properties: commit: type: string example: a1b2c3d4 services: type: object nullable: true additionalProperties: type: object properties: status: type: string example: down latency_ms: type: number format: float example: 950.0 open_connections: type: integer example: 10 in_use: type: integer example: 4 idle: type: integer example: 6 driver: type: string example: postgres error: type: string example: Database connection failed example: { "code": 503, "data": "ERROR", "success": true, "status": "unhealthy", "version": "3.0.0", "uptime": 86410, "timestamp": "2024-01-01T12:05:00Z", "metrics": { "goroutines": 55, "go_version": "go1.21.5", "cpu_count": 8, "go_max_procs": 8, }, "environment": { "containerized": false, "hostname": "digigo-01", "app_env": "production", "app_region": "us-east-1", }, "services": { "database": { "status": "down", "latency_ms": 950.0, "open_connections": 10, "in_use": 4, "idle": 6, "driver": "postgres", "error": "Database connection failed", }, }, } /webhook: get: tags: - Webhook summary: Shows webhook description: | Gets the configured webhook and subscribed events. ## Webhook The following _webhook_ endpoints are used to get or set the webhook that will be called whenever a message or event is received. Available event types are: **Messages and Communication:** * Message - Incoming/outgoing messages * UndecryptableMessage - Messages that couldn't be decrypted * Receipt - Message delivery receipts * MediaRetry - Media message retry events * ReadReceipt - Message read receipts **Groups and Contacts:** * GroupInfo - Group information changes * JoinedGroup - User joined/left group events * Picture - Profile/group picture changes * BlocklistChange - Blocklist modification events * Blocklist - Complete blocklist updates **Connection and Session:** * Connected - Successfully connected to WhatsApp * Disconnected - Disconnected from WhatsApp * ConnectFailure - Connection failure events * KeepAliveRestored - Connection keep-alive restored * KeepAliveTimeout - Connection keep-alive timeout * LoggedOut - User logged out * ClientOutdated - Client version outdated * TemporaryBan - Temporary account ban * StreamError - WebSocket stream errors * StreamReplaced - WebSocket stream replaced * PairSuccess - Device pairing successful * PairError - Device pairing failed * QR - QR code generation/updates * QRScannedWithoutMultidevice - QR scanned without multidevice **Privacy and Settings:** * PrivacySettings - Privacy settings changes * PushNameSetting - Push name updates * UserAbout - User about/status changes **Synchronization and State:** * AppState - Application state changes * AppStateSyncComplete - App state sync completed * HistorySync - Message history synchronization * OfflineSyncCompleted - Offline sync completed * OfflineSyncPreview - Offline sync preview **Calls:** * CallOffer - Incoming call offer * CallAccept - Call accepted * CallTerminate - Call terminated * CallOfferNotice - Call offer notification * CallRelayLatency - Call relay latency updates **Presence and Activity:** * Presence - User online/offline status * ChatPresence - Chat typing/recording status **Identity and Security:** * IdentityChange - User identity changes **Errors:** * CATRefreshError - CAT token refresh errors **Newsletter (WhatsApp Channels):** * NewsletterJoin - Joined newsletter/channel * NewsletterLeave - Left newsletter/channel * NewsletterMuteChange - Newsletter mute status change * NewsletterLiveUpdate - Newsletter live updates **Facebook/Meta Bridge:** * FBMessage - Facebook messages **Special:** * All - Subscribes to all event types above security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "subscribe": ["Message", "ReadReceipt"], "webhook": "https://example.net/webhook", }, "success": true, } post: tags: - Webhook summary: Sets webhook description: | Sets the webhook that will be used to POST information when messages are received and configures the events to subscribe to. ## Webhook The following _webhook_ endpoints are used to get or set the webhook that will be called whenever a message or event is received. Available event types are: **Messages and Communication:** * Message - Incoming/outgoing messages * UndecryptableMessage - Messages that couldn't be decrypted * Receipt - Message delivery receipts * MediaRetry - Media message retry events * ReadReceipt - Message read receipts **Groups and Contacts:** * GroupInfo - Group information changes * JoinedGroup - User joined/left group events * Picture - Profile/group picture changes * BlocklistChange - Blocklist modification events * Blocklist - Complete blocklist updates **Connection and Session:** * Connected - Successfully connected to WhatsApp * Disconnected - Disconnected from WhatsApp * ConnectFailure - Connection failure events * KeepAliveRestored - Connection keep-alive restored * KeepAliveTimeout - Connection keep-alive timeout * LoggedOut - User logged out * ClientOutdated - Client version outdated * TemporaryBan - Temporary account ban * StreamError - WebSocket stream errors * StreamReplaced - WebSocket stream replaced * PairSuccess - Device pairing successful * PairError - Device pairing failed * QR - QR code generation/updates * QRScannedWithoutMultidevice - QR scanned without multidevice **Privacy and Settings:** * PrivacySettings - Privacy settings changes * PushNameSetting - Push name updates * UserAbout - User about/status changes **Synchronization and State:** * AppState - Application state changes * AppStateSyncComplete - App state sync completed * HistorySync - Message history synchronization * OfflineSyncCompleted - Offline sync completed * OfflineSyncPreview - Offline sync preview **Calls:** * CallOffer - Incoming call offer * CallAccept - Call accepted * CallTerminate - Call terminated * CallOfferNotice - Call offer notification * CallRelayLatency - Call relay latency updates **Presence and Activity:** * Presence - User online/offline status * ChatPresence - Chat typing/recording status **Identity and Security:** * IdentityChange - User identity changes **Errors:** * CATRefreshError - CAT token refresh errors **Newsletter (WhatsApp Channels):** * NewsletterJoin - Joined newsletter/channel * NewsletterLeave - Left newsletter/channel * NewsletterMuteChange - Newsletter mute status change * NewsletterLiveUpdate - Newsletter live updates **Facebook/Meta Bridge:** * FBMessage - Facebook messages **Special:** * All - Subscribes to all event types above security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/WebhookSet" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "WebhookURL": "https://example.net/webhook", "Events": ["Message", "ReadReceipt"], }, "success": true, } delete: tags: - Webhook summary: Deletes webhook description: Removes the configured webhook and clears events for the user security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Webhook and events deleted successfully" }, "success": true, } put: tags: - Webhook summary: Updates webhook description: | Updates the webhook URL, events, and activation status. ## Webhook The following _webhook_ endpoints are used to get or set the webhook that will be called whenever a message or event is received. Available event types are: **Messages and Communication:** * Message - Incoming/outgoing messages * UndecryptableMessage - Messages that couldn't be decrypted * Receipt - Message delivery receipts * MediaRetry - Media message retry events * ReadReceipt - Message read receipts **Groups and Contacts:** * GroupInfo - Group information changes * JoinedGroup - User joined/left group events * Picture - Profile/group picture changes * BlocklistChange - Blocklist modification events * Blocklist - Complete blocklist updates **Connection and Session:** * Connected - Successfully connected to WhatsApp * Disconnected - Disconnected from WhatsApp * ConnectFailure - Connection failure events * KeepAliveRestored - Connection keep-alive restored * KeepAliveTimeout - Connection keep-alive timeout * LoggedOut - User logged out * ClientOutdated - Client version outdated * TemporaryBan - Temporary account ban * StreamError - WebSocket stream errors * StreamReplaced - WebSocket stream replaced * PairSuccess - Device pairing successful * PairError - Device pairing failed * QR - QR code generation/updates * QRScannedWithoutMultidevice - QR scanned without multidevice **Privacy and Settings:** * PrivacySettings - Privacy settings changes * PushNameSetting - Push name updates * UserAbout - User about/status changes **Synchronization and State:** * AppState - Application state changes * AppStateSyncComplete - App state sync completed * HistorySync - Message history synchronization * OfflineSyncCompleted - Offline sync completed * OfflineSyncPreview - Offline sync preview **Calls:** * CallOffer - Incoming call offer * CallAccept - Call accepted * CallTerminate - Call terminated * CallOfferNotice - Call offer notification * CallRelayLatency - Call relay latency updates **Presence and Activity:** * Presence - User online/offline status * ChatPresence - Chat typing/recording status **Identity and Security:** * IdentityChange - User identity changes **Errors:** * CATRefreshError - CAT token refresh errors **Newsletter (WhatsApp Channels):** * NewsletterJoin - Joined newsletter/channel * NewsletterLeave - Left newsletter/channel * NewsletterMuteChange - Newsletter mute status change * NewsletterLiveUpdate - Newsletter live updates **Facebook/Meta Bridge:** * FBMessage - Facebook messages **Special:** * All - Subscribes to all event types above security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/WebhookUpdate" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Webhook": "https://example.net/webhook", "Events": ["Message", "ReadReceipt"], "active": true, }, "success": true, } /session/connect: post: tags: - Session summary: connects to WhatsApp servers description: "Initiates connection to WhatsApp servers.\n\nIf there is no previous session created, it will generate a QR code that can be retrieved via the [qr](#/Session/get_session_qr) API call.\n\nIf the optional Subscribe is supplied it will limit webhooks to the specified event types. Available events: Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, All.\n\nIf no Subscribe is supplied it will subscribe to All events.\n\nIf Immediate is set to false, the action will wait for 10 seconds to retrieve actual connection status from whatsapp, otherwise it will return immediatly.\n\nWhen setting Immediate to true you should check for actual connection status after a few seconds via the [status](#/Session/get_session_status) API call as your connection might fail if the session was closed from another device.\n\n**Connection Behavior:**\n- If you have a valid stored session (previously logged in), it will connect directly without requiring QR code scanning\n- If no valid session exists, a QR code will be generated that must be scanned with your phone\n- Use this endpoint after calling [disconnect](#/Session/post_session_disconnect) to reconnect without QR scanning" security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/Connect" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "details": "Connected!", "events": "Message", "jid": "5491155555555.0:53@s.whatsapp.net", "webhook": "https://some.site/webhook?request=parameter", }, "success": true, } /session/disconnect: post: tags: - Session summary: disconnects from WhatsApp servers description: "**Soft Disconnect - WebSocket Only**\n\nCloses the WebSocket connection to WhatsApp servers while preserving your session credentials. This is a **non-destructive operation** that:\n\n- ✅ Maintains your login session and stored credentials\n- ✅ Allows reconnection using [connect](#/Session/post_session_connect) **without QR code scanning**\n- ✅ Preserves all chat history and settings\n- ✅ Keeps the session valid for future connections\n\n**Use Cases:**\n- Temporarily pause message receiving (maintenance, debugging)\n- Switch between different webhook configurations\n- Restart connection without losing authentication\n- Network troubleshooting\n\n**Important:** After disconnect, you can reconnect instantly with the connect endpoint. No QR code scanning required as your WhatsApp session remains active and valid.\n\n**Comparison with other endpoints:**\n- Use `disconnect` for temporary connection suspension\n- Use [logout](#/Session/post_session_logout) for complete session termination\n- Use [refresh](#/Session/post_session_refresh) for session cleanup without disconnection" security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Disconnected" }, "success": true, } /session/logout: post: tags: - Session summary: Logs out from WhatsApp description: "**Complete Session Termination - Full Logout**\n\nPerforms a complete logout and terminates all connections to WhatsApp servers. This is a **destructive operation** that:\n\n- ❌ **Completely removes** your stored session and credentials\n- ❌ **Requires QR code scanning** for next connection\n- ❌ Closes all WebSocket connections permanently\n- ❌ Clears all local session data and authentication tokens\n- ❌ Invalidates the session on WhatsApp's servers\n\n**What happens after logout:**\n1. Your device is removed from WhatsApp's active device list\n2. All stored session credentials are permanently deleted\n3. Next [connect](#/Session/post_session_connect) call will require fresh QR code authentication\n4. You must scan the QR code with your phone to re-establish the session\n\n**Use Cases:**\n- Permanently removing the API connection from your WhatsApp account\n- Security purposes (revoke access completely)\n- Switching to a different WhatsApp account\n- Full reset of the API integration\n\n**Important:** This action cannot be undone. After logout, you must go through the complete setup process again, including QR code scanning.\n\n**Comparison with other endpoints:**\n- Use [disconnect](#/Session/post_session_disconnect) for temporary suspension (preserves session)\n- Use `logout` for permanent termination (requires new QR setup)\n- Use [refresh](#/Session/post_session_refresh) for session cleanup without logout" security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Logged out" }, "success": true, } /session/refresh: post: tags: - Session summary: Complete session refresh with full synchronization description: | **Complete Session Refresh with Full Synchronization** Performs a complete session refresh including reconnection and optional full synchronization of all WhatsApp data. This is the most comprehensive refresh operation available. **What this endpoint does:** 1. Disconnects and reconnects to WhatsApp servers 2. Synchronizes all 5 App State patch types (contacts, chats, settings) 3. Checks and uploads PreKeys if needed (encryption keys) 4. Refreshes Privacy Settings from server 5. Requests automatic recovery for any failed syncs **Sync Options (all default to true):** - `sync_app_state`: Sync all 5 app state patches (critical_block, critical_unblock_low, regular_low, regular_high, regular) - `refresh_prekeys`: Check server prekey count and upload if low (<5 keys) - `refresh_privacy`: Force refresh of privacy settings from server - `auto_recovery`: If app state sync fails, automatically request recovery from primary device **App State Patches Explained:** - **critical_block**: User settings (push name, locale) - **critical_unblock_low**: Contact list - **regular_low**: Chat settings (pin, archive, unarchive behavior) - **regular_high**: More chat settings (mute, starred messages) - **regular**: Protocol info (key expiration) **PreKeys:** PreKeys are encryption keys used by the Signal Protocol. WhatsApp servers need a pool of these keys to establish encrypted sessions. This endpoint checks if the server has enough keys and uploads more if needed. **Auto Recovery:** If app state sync fails (corrupted data, version mismatch), the auto_recovery feature uses `BuildAppStateRecoveryRequest` to request an unencrypted snapshot from your primary device (phone). **Typical Duration:** 7-10 seconds (3s reconnect + 2-5s app state + 1s prekeys + 1s privacy) **Use Cases:** - Complete session refresh after long disconnection - Recover from sync issues or corrupted local state - Ensure all data is up-to-date after configuration changes - Periodic maintenance for production deployments - Troubleshoot message delivery issues security: - ApiKeyAuth: [] requestBody: required: false content: application/json: schema: type: object properties: sync_app_state: type: boolean description: Sync all 5 app state patch types (contacts, chats, settings). Default true. default: true example: true refresh_prekeys: type: boolean description: Check server prekey count and upload new keys if below threshold. Default true. default: true example: true refresh_privacy: type: boolean description: Force refresh of privacy settings from WhatsApp servers. Default true. default: true example: true auto_recovery: type: boolean description: If app state sync fails, automatically request recovery from primary device. Default true. default: true example: true example: sync_app_state: true refresh_prekeys: true refresh_privacy: true auto_recovery: true responses: 200: description: Session refreshed successfully with sync results content: application/json: schema: type: object properties: Details: type: string example: "Connection refresh completed" refreshSuccess: type: boolean example: true wasConnected: type: boolean example: true wasLoggedIn: type: boolean example: true newConnected: type: boolean example: true newLoggedIn: type: boolean example: true jid: type: string example: "5521999999999@s.whatsapp.net" sync_options: type: object properties: sync_app_state: type: boolean refresh_prekeys: type: boolean refresh_privacy: type: boolean auto_recovery: type: boolean sync: type: object properties: app_state: type: array items: type: object properties: name: type: string success: type: boolean error: type: string duration: type: string recovery_requested: type: boolean app_state_success: type: boolean prekeys: type: object properties: checked: type: boolean server_count: type: integer upload_triggered: type: boolean error: type: string privacy_settings: type: object properties: fetched: type: boolean error: type: string total_duration: type: string example: Details: "Connection refresh completed" refreshSuccess: true wasConnected: true wasLoggedIn: true newConnected: true newLoggedIn: true jid: "5521999999999@s.whatsapp.net" sync_options: sync_app_state: true refresh_prekeys: true refresh_privacy: true auto_recovery: true sync: app_state: - name: "critical_block" success: true duration: "1.234s" recovery_requested: false - name: "critical_unblock_low" success: true duration: "0.856s" recovery_requested: false - name: "regular_low" success: true duration: "0.523s" recovery_requested: false - name: "regular_high" success: true duration: "0.412s" recovery_requested: false - name: "regular" success: true duration: "0.678s" recovery_requested: false app_state_success: true prekeys: checked: true server_count: 47 upload_triggered: false privacy_settings: fetched: true total_duration: "4.521s" 400: description: Bad request - no JID found, QR scan required content: application/json: schema: example: { "code": 400, "error": "no JID found, QR scan required for initial pairing", "success": false, } 500: description: Connection refresh failed content: application/json: schema: example: { "code": 500, "error": "Failed to refresh connection", "refreshSuccess": false, "wasConnected": true, "wasLoggedIn": true, "newConnected": false, "newLoggedIn": false, } /session/status: get: tags: - Session summary: Gets connection and session status description: Gets status from connection, including websocket connection and logged in status (session) security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: type: object required: - code - data - success properties: code: type: integer example: 200 data: $ref: "#/definitions/SessionStatus" success: type: boolean example: true example: { "code": 200, "success": true, "data": { "id": "bec45bb93cbd24cbec32941ec3c93a12", "name": "Some User", "avatar_url": "https://example.com/avatar.jpg", "connected": true, "loggedIn": true, "hasClient": true, "connectionHealth": "connected", "lastSuccessfulConnect": 1705312845, "autoReconnectErrors": 0, "enableAutoReconnect": true, "expiration": 86400, "token": "d030sl9aDL39sl3075zz", "jid": "5491155551122:12@s.whatsapp.net", "webhook": "https://some.domain/webhook", "events": "All", "proxy_url": "", "qrcode": "", "skip_media_download": false, "skip_groups": false, "skip_newsletters": false, "skip_broadcasts": false, "skip_own_messages": false, "echo_api_messages": false, "skip_calls": false, "call_reject_message": "Sorry, I cannot take calls at the moment.", "call_reject_type": "busy", "globalTransportSkips": { "skipGlobalWebhook": false, "skipGlobalRabbitMQ": false, "skipGlobalSQS": false, "skipGlobalRedis": false, "skipGlobalWebSocket": false, "skipGlobalS3": false, }, "isFromAPI": false, "proxy_config": { "enabled": false, "proxy_url": "" }, "s3_config": { "enabled": false }, "rabbitmq_config": { "enabled": false }, "timestamp": 1705312845, }, } /session/pairphone: post: tags: - Session summary: Gets pair by phone code description: Gets the code to enter into whatsapp client when pairing by phone number instead of QR code security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/Pairphone" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "LinkingCode": "9H3J-H3J8" }, "success": true, } /session/qr: get: tags: - Session summary: Gets QR code for scanning description: Gets QR code if the user is connected but not logged in. If the user is already logged in, QRCode will be empty. security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "QRCode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX///8AAABVwtN+AAAEw0lEQVR42uyZPa7zqhaGX0ThLmsCkZlGCktMKaU76FxmSkgUmQZWJkA6CuT3avlLvrNvvRMX9x6KXWQ/UhCsn2cR/Lv+v5YhudQ6njEs1bBjqGYDwlJJpoOAArtUbK4Pi5jN3qPAlCkstcAeBazMUaoj78RpxGW4yWYzWVfmzwFLlLX4O+VkkucN5tFDOxiIAvfoA/X4uVQ4sgUcCBTYCG7AEGGKvbdrBabQ8OOyvg3ovm4ynqfLXJ9rvi+303ie5vm/gvZXgK6BLC7fo5hiG4KwW7b6I/2+DJi1+ybVFQyx6o6bbKPVDCyjTwcBZB9uevBtAEafhiosCFH/4kNA8i1gg02B3KxezGbzEjUCDgIwYppR3SNdgtY3H0M1j8xFzCscvg/8uQvZAB9piidv1RXfZhbHdAwAlzsCNCaJDdMF4WQeeSGACZ8BMNl4FZYJA7j2YalPPhhngetHAaZPcyBg2wyYdAk0fKQ5yPja5PcBzTZW4uxJ2bTGwmxnu/BH4vwSgEsYItcCH+VZJt/AYhmHatbXdX8d2JvaTVzxCVW2aVhqheXSqvnR9b4L6AoUx3zX+jZd5rDB5jbLuv0txd8GRs+liuv+TsKloQWujxxRYf5s8gOA7fMVK9PQuDtMNCx2ibIdCMCy1s0yQU6Od9bqim1BuzoOAgzTHOiKv0d5Mt+XClN8DBxN/wxg2G2DbDYNJExCqE+Ne8poXoLxdUA/w5VrnxBQ9fjlqaJMwWgPAzLjtfKRW4A21ojnStX0dX2d5PeB0fawu2pChcuM4bk+tLmbMn0GMJslb5ptDXySbb5W1+0SyVcJOgRIQxSc7X0RUSvGs2DSeaz4gwCMNi/7XNACZc0KbPBtruv2KQA+DVFladBvt4xywhmh1Xd2fx8wzGTUltqCWrHWgqL7Jg8E0hSiFJfbUJ/Fpx3L1OHsVR8+APgoZMclUKvcft2+zTBrwjHArosim4ZcfW4Y4lVWnYXg2A8C9C5aEFXDoEJzmXFyfZoH/p0Wvw7oXoZbNQ823ase1wk2DQ3u7XK/BkzOqovwpM68Ko+jUyPFu6F8H4DvqsAuaUMZJ6+azjTPdS32KMBkLnpQ3VPnbsZgiktALW91/wDQEV5V7gT4JT6L62GRzeV0EDDC7rVFax2ZW6Aa6V5h/FEAgBlSbLrMVScU1s09+jxwG/9q87cB/Yxw3acBsk2Yw+nPf9Y1p88ARlNPtvPkF3LlPQYp8MtSx/FtpF8H4DNrZd8fOtTOxJSzXdo/c/fXAbN2DLeKs1dxHeEZZVWaju/3h18CcDk3qePZpllglDZ89MCq8nIQoDPAVaPi3iAFFwS1xjjr+HcYwD+hri216vBZzQbbZsE44RhAp+sQxfTpApGCoV1NOfsl4pX+nwC65a1uLnkK9TSuVTOhaQ4cBOzvtDcZXU5Bdl28SrF9HqrZJhwD7O/VsZpi7xSz7pXW6ahQ1/dB/RrYf2QhLBmr1lNINVRZfw9BBwArc4SszGlWWd2fxB9cFvJQYKnUUWAgV22y5v1e/ffHpiOAqMLCiOpymwNGtxvk9s8mfwcU2CiydqvJbdKuSX0K8a/KHQDsMQkyeVbtISFif8mRcfwRtF8F/l3/O+s/AQAA///lM0dZSaTeTQAAAABJRU5ErkJggg==", }, "success": true, } /session/proxy: post: tags: - Session summary: Set Proxy Configuration description: | Sets or disables the proxy configuration for the user. Provide a JSON payload with "proxy_url" (e.g. "http://host:port" or "socks5://user:pass@host:port") and "enable" (boolean). security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: proxy_url: type: string description: Proxy URL in format "http://host:port" or "socks5://user:pass@host:port" enable: type: boolean description: Whether to enable or disable the proxy. required: - proxy_url - enable responses: "200": description: Proxy configured successfully content: application/json: schema: type: object properties: Details: type: string example: Proxy configured successfully ProxyURL: type: string example: socks5://user:pass@host:port "400": description: Bad Request "500": description: Internal Server Error /session/s3/config: post: tags: - Session S3 summary: Configure S3 Storage description: | Configures S3 storage settings for the user to store media files. Supports AWS S3, MinIO, Backblaze B2, and other S3-compatible services. When enabled, media files will be uploaded to S3 and can be accessed via public URLs. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/S3Config" responses: 200: description: S3 configuration saved successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "S3 configuration saved successfully", "Enabled": true, }, "success": true, } 400: description: Bad Request 500: description: Internal Server Error get: tags: - Session S3 summary: Get S3 Configuration description: Retrieves the current S3 storage configuration for the user. security: - ApiKeyAuth: [] responses: 200: description: S3 configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "enabled": true, "endpoint": "https://s3.amazonaws.com", "region": "us-east-1", "bucket": "my-bucket", "access_key": "***", "path_style": false, "public_url": "", "media_delivery": "both", "retention_days": 30, }, "success": true, } 500: description: Internal Server Error delete: tags: - Session S3 summary: Delete S3 Configuration description: Removes the S3 storage configuration for the user and reverts to default base64 media delivery. security: - ApiKeyAuth: [] responses: 200: description: S3 configuration deleted successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "S3 configuration deleted successfully" }, "success": true, } 500: description: Internal Server Error /session/s3/test: post: tags: - Session S3 summary: Test S3 Connection description: Tests the S3 connection using the current configuration to ensure it's working properly. security: - ApiKeyAuth: [] responses: 200: description: S3 connection test successful content: application/json: schema: example: { "code": 200, "data": { "Details": "S3 connection test successful", "Bucket": "my-bucket", "Region": "us-east-1", }, "success": true, } 400: description: S3 is not enabled or configuration error 500: description: S3 connection test failed /session/rabbitmq/config: post: tags: - Session RabbitMQ summary: Configure RabbitMQ - Advanced with Dynamic Queues description: | Configures RabbitMQ settings for the user to publish WhatsApp events with **dynamic queues per event type** and **auto-recovery system**. **🚀 FILAS DINÂMICAS POR EVENTO:** - Use placeholders `{user_id}` and `{event_type}` in queue/routing_key patterns - System automatically creates event-specific queues as events arrive - Example: `user_abc123_event_Message`, `user_abc123_event_Receipt`, etc. **⚡ AUTO-RECOVERY SYSTEM:** - Health check every 30 seconds with automatic reconnection - Circuit breaker prevents overload during connectivity issues - Connection pool with retry logic and exponential backoff - Queue cache prevents unnecessary recreations Supports AMQP protocol with exchanges, queues, and routing keys. When enabled, WhatsApp events will be published to the configured RabbitMQ server with enterprise-grade reliability. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/RabbitMQConfig" responses: 200: description: RabbitMQ configuration saved successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "RabbitMQ configuration saved successfully", "Enabled": true, }, "success": true, } 400: description: Bad Request 500: description: Internal Server Error get: tags: - Session RabbitMQ summary: Get RabbitMQ Configuration with Queue Statistics description: Retrieves the current RabbitMQ configuration for the user including dynamic queue statistics and created queues list. security: - ApiKeyAuth: [] responses: 200: description: RabbitMQ configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "config": { "enabled": true, "url": "amqp://user:***@localhost:5672/", "exchange": "whatsapp.events", "exchange_type": "topic", "queue": "whatsapp.user.{user_id}", "queue_type": "classic", "routing_key": "whatsapp.{event_type}", "events": "Message,ReadReceipt,All", "durable": true, "auto_delete": false, "exclusive": false, "no_wait": false, "delivery_mode": 2, "dead_letter_exchange": "dlx.whatsapp", "dead_letter_routing_key": "dlq.events", "message_ttl": 86400000, "max_length": 100000, "max_length_bytes": 104857600, "queue_arguments": '{"x-overflow":"reject-publish"}', "exchange_arguments": "{}", }, "stats": { "active_queues": [ "whatsapp.user.abc123_Message", "whatsapp.user.abc123_Receipt", ], "total_published": 15420, "last_publish": "2024-01-15T10:30:00Z", }, }, "success": true, } 500: description: Internal Server Error delete: tags: - Session RabbitMQ summary: Delete RabbitMQ Configuration description: Removes the RabbitMQ configuration for the user and disables RabbitMQ event publishing. security: - ApiKeyAuth: [] responses: 200: description: RabbitMQ configuration deleted successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "RabbitMQ configuration deleted successfully", }, "success": true, } 500: description: Internal Server Error /session/rabbitmq/test: post: tags: - Session RabbitMQ summary: Test RabbitMQ Connection description: Tests the RabbitMQ connection using the current configuration to ensure it's working properly. security: - ApiKeyAuth: [] responses: 200: description: RabbitMQ connection test successful content: application/json: schema: example: { "code": 200, "data": { "Details": "RabbitMQ connection test successful", "Host": "localhost", "Port": 5672, "Exchange": "whatsapp.events", }, "success": true, } 400: description: RabbitMQ is not enabled or configuration error 500: description: RabbitMQ connection test failed /session/skipmedia/config: post: tags: - Session Skips summary: Configure Skip Media Download description: | Configure whether to skip downloading media files (images, videos, audio, documents, stickers) during WhatsApp events. When enabled, events will only contain WhatsApp metadata without base64 content or S3 uploads, dramatically improving performance for high-volume scenarios. **Performance Benefits:** - ⚡ Faster event processing (up to 90% improvement) - 📊 Reduced bandwidth usage - 💾 Lower storage requirements - 🔄 Better performance for high-volume scenarios - 📱 Original WhatsApp metadata preserved **Configuration Hierarchy:** 1. Command Line Flag (-skipmedia) - Highest priority 2. Environment Variable (GLOBAL_SKIP_MEDIA_DOWNLOAD) - Global setting 3. User Configuration (skip_media_download) - Individual setting 4. Default Behavior - Normal media processing security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipMediaConfig" responses: 200: description: Skip media download configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip media download configuration updated successfully", "SkipMediaDownload": true, }, "success": true, } 400: description: Invalid request payload 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Media Download Configuration description: | Retrieves the current skip media download configuration for the authenticated user, including both user-specific and global settings. **Response includes:** - UserSkipMediaDownload: Individual user setting - GlobalSkipMediaDownload: Server-wide setting (read-only) - Configuration hierarchy status security: - ApiKeyAuth: [] responses: 200: description: Skip media download configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "UserSkipMediaDownload": false, "GlobalSkipMediaDownload": false, "Details": "Skip media download configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/skipgroups/config: post: tags: - Session Skips summary: Configure Skip Groups description: | Configure whether to skip processing messages from WhatsApp groups. When enabled, the system will ignore all messages from group chats, processing only direct messages. This can improve performance and reduce processing overhead for applications that don't need group functionality. Priority order: 1. User Configuration (skip_groups) - Individual setting 2. Global setting (if implemented) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipGroupsConfig" responses: 200: description: Skip groups configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip groups configuration updated successfully", "SkipGroups": true, }, "success": true, } 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Groups Configuration description: | Retrieves the current skip groups configuration for the authenticated user. Returns: - UserSkipGroups: Individual user setting security: - ApiKeyAuth: [] responses: 200: description: Skip groups configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "UserSkipGroups": false, "Details": "Skip groups configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/skipnewsletters/config: post: tags: - Session Skips summary: Configure Skip Newsletters description: | Configure whether to skip processing messages from WhatsApp newsletters. When enabled, the system will ignore all messages from newsletter channels, processing only direct messages and groups. This can improve performance and reduce processing overhead for applications that don't need newsletter functionality. Priority order: 1. User Configuration (skip_newsletters) - Individual setting 2. Global setting (if implemented) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipNewslettersConfig" responses: 200: description: Skip newsletters configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip newsletters configuration updated successfully", "SkipNewsletters": true, }, "success": true, } 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Newsletters Configuration description: | Retrieves the current skip newsletters configuration for the authenticated user. Returns: - SkipNewsletters: Individual user setting security: - ApiKeyAuth: [] responses: 200: description: Skip newsletters configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "SkipNewsletters": false, "Details": "Skip newsletters configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/skipbroadcasts/config: post: tags: - Session Skips summary: Configure Skip Broadcasts description: | Configure whether to skip processing messages from WhatsApp broadcasts and status updates. When enabled, the system will ignore all messages from broadcast lists and status updates, processing only direct messages, groups, and newsletters. This can improve performance and reduce processing overhead for applications that don't need broadcast functionality. Priority order: 1. User Configuration (skip_broadcasts) - Individual setting 2. Global setting (if implemented) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipBroadcastsConfig" responses: 200: description: Skip broadcasts configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip broadcasts configuration updated successfully", "SkipBroadcasts": true, }, "success": true, } 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Broadcasts Configuration description: | Retrieves the current skip broadcasts configuration for the authenticated user. Returns: - SkipBroadcasts: Individual user setting security: - ApiKeyAuth: [] responses: 200: description: Skip broadcasts configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "SkipBroadcasts": false, "Details": "Skip broadcasts configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/skipownmessages/config: post: tags: - Session Skips summary: Configure Skip Own Messages description: | Configure whether to skip processing your own sent messages (IsFromMe: true). When enabled, the system will ignore all messages that were sent by you, processing only messages received from others. This can improve performance and reduce processing overhead for applications that don't need to track outgoing messages. Priority order: 1. User Configuration (skip_own_messages) - Individual setting 2. Global setting (if implemented) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipOwnMessagesConfig" responses: 200: description: Skip own messages configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip own messages configuration updated successfully", "SkipOwnMessages": true, }, "success": true, } 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Own Messages Configuration description: | Retrieves the current skip own messages configuration for the authenticated user. Returns: - SkipOwnMessages: Individual user setting security: - ApiKeyAuth: [] responses: 200: description: Skip own messages configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "SkipOwnMessages": false, "Details": "Skip own messages configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/skipcalls/config: post: tags: - Session Skips summary: Configure Skip Calls description: | Configure automatic call rejection settings for the session. When enabled, all incoming calls will be automatically rejected and an optional custom message will be sent to the caller. Features: - Automatic call rejection - Customizable rejection message - Configurable rejection type (busy, declined, unavailable) - Zero-query cache optimization Priority order: 1. User Configuration (skip_calls) - Individual setting 2. Global setting (if implemented) security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SkipCallsConfig" responses: 200: description: Skip calls configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Skip calls configuration updated successfully", "SkipCalls": true, "RejectMessage": "Sorry, I cannot take calls at the moment. Please send a message.", "RejectType": "busy", }, "success": true, } 400: description: Bad Request - Invalid rejection type content: application/json: schema: example: { "code": 400, "error": "invalid reject_type, must be: busy, declined, or unavailable", "success": false, } 500: description: Internal Server Error get: tags: - Session Skips summary: Get Skip Calls Configuration description: | Retrieves the current skip calls configuration for the authenticated user. Returns: - SkipCalls: Individual user setting - RejectMessage: Custom message sent to callers - RejectType: Type of call rejection used security: - ApiKeyAuth: [] responses: 200: description: Skip calls configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "SkipCalls": false, "RejectMessage": "Sorry, I cannot take calls at the moment.", "RejectType": "busy", "Details": "Skip calls configuration retrieved successfully", }, "success": true, } 500: description: Internal Server Error /session/globaltransports/config: post: tags: - Session Global Transports summary: Configure global transport skip flags operationId: configureGlobalTransportSkips description: | Configure per-transport skip flags that the global dispatcher consults before enriching and fan-out events. Use these flags when you need to disable the global webhook, RabbitMQ, SQS, Redis, WebSocket, or shared S3 enrichment for a specific tenant without affecting per-user transports. Behavior: - Updates only the transports included in the payload (partial updates supported) - Triggers an immediate cache refresh so dispatcher decisions reflect the new state instantly - Does not affect per-user transports (local webhooks/rabbitmq); only the shared/global dispatcher pipeline security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GlobalTransportSkipsRequest" responses: 200: description: Global transport skip flags updated successfully content: application/json: schema: $ref: "#/definitions/GlobalTransportSkipsResponse" example: { "code": 200, "data": { "skipGlobalWebhook": false, "skipGlobalRabbitMQ": true, "skipGlobalSQS": false, "skipGlobalRedis": false, "skipGlobalWebSocket": false, "skipGlobalS3": true, "details": "Global transport skip configuration updated successfully", }, "success": true, } 400: description: Bad Request - No valid fields provided content: application/json: schema: example: { "code": 400, "error": "no fields provided", "success": false, } 401: description: Unauthorized - user token required content: application/json: schema: example: { "code": 401, "error": "unauthorized", "success": false } 500: description: Internal Server Error - database or cache failure content: application/json: schema: example: { "code": 500, "error": "failed to update transport configuration", "success": false, } get: tags: - Session Global Transports summary: Get global transport skip flags operationId: getGlobalTransportSkips description: | Retrieve the current snapshot of global transport skip flags for the authenticated session. The response mirrors what the global dispatcher caches, so you can inspect which transports (webhook, RabbitMQ, SQS, Redis, WebSocket, S3 enrichment) are disabled for the tenant. security: - ApiKeyAuth: [] responses: 200: description: Global transport skip flags retrieved successfully content: application/json: schema: $ref: "#/definitions/GlobalTransportSkipsResponse" example: { "code": 200, "data": { "skipGlobalWebhook": false, "skipGlobalRabbitMQ": false, "skipGlobalSQS": false, "skipGlobalRedis": false, "skipGlobalWebSocket": false, "skipGlobalS3": false, "details": "Global transport skip configuration retrieved successfully", }, "success": true, } 401: description: Unauthorized - user token required content: application/json: schema: example: { "code": 401, "error": "unauthorized", "success": false } 500: description: Internal Server Error - cache or database failure content: application/json: schema: example: { "code": 500, "error": "failed to load user configuration", "success": false, } /session/presence/config: post: tags: - Session Presence summary: Configure Auto Presence Unavailable operationId: configureAutoPresenceUnavailable description: | Enable or disable automatic presence unavailable after connection. When enabled, the system sends PresenceUnavailable 3 seconds after the protocol-required PresenceAvailable, preserving push notifications on the phone while keeping the API session active. Behavior: - Default: false (standard behavior - stays as Available after connection) - When enabled: Available → 3s delay → Unavailable (phone keeps receiving push notifications) - The PresenceAvailable is still sent first (required for WhatsApp protocol handshake) - Manual presence control via POST /user/presence is not affected security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - enabled properties: enabled: type: boolean description: Whether to automatically send PresenceUnavailable after connection example: enabled: true responses: 200: description: Auto presence unavailable configuration updated successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Auto presence unavailable configuration updated successfully", "AutoPresenceUnavailable": true, }, "success": true, } 400: description: Bad Request - Invalid payload 401: description: Unauthorized - user token required 500: description: Internal Server Error get: tags: - Session Presence summary: Get Auto Presence Unavailable Configuration operationId: getAutoPresenceUnavailableConfig description: | Retrieves the current auto presence unavailable configuration for the authenticated user. security: - ApiKeyAuth: [] responses: 200: description: Auto presence unavailable configuration retrieved successfully content: application/json: schema: example: { "code": 200, "data": { "AutoPresenceUnavailable": false, "Details": "Auto presence unavailable configuration retrieved successfully", }, "success": true, } 401: description: Unauthorized - user token required 500: description: Internal Server Error /user/info: post: tags: - User summary: Get user information description: Gets detailed information about WhatsApp users, including status, profile picture, verified names, and device information security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: Phone: oneOf: - type: string description: Single phone number example: "5521971532700" - type: array items: type: string description: Array of phone numbers example: ["5521971532700", "5521979232690"] required: - Phone additionalProperties: false examples: responses: "200": description: User information retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 success: type: boolean example: true data: type: object properties: users: type: object description: Object containing user information indexed by WhatsApp JID additionalProperties: type: object properties: jid: type: string description: WhatsApp JID example: "5521971532700@s.whatsapp.net" status: type: string description: User status message example: "Hey there! I am using WhatsApp." picture_id: type: string description: Profile picture ID example: "1729003008" verified_name: type: string description: Verified business name (if available) example: "Business Name" business_name: type: string description: Business name (if different from verified name) example: "My Business" lid: type: string description: "Linked ID (LID) - Privacy feature JID used in groups when user hasn't shared phone number publicly. Only present for group members with privacy protection enabled." example: "1234567890abcd@lid" is_business_account: type: boolean description: Whether this is a business account example: false device_count: type: integer description: Total number of connected devices example: 4 first_device: type: string description: JID of the primary device example: "5521971532700@s.whatsapp.net" devices: type: array description: Detailed information about all connected devices items: type: object properties: user: type: string description: User number example: "5521971532700" agent: type: string description: Device agent ID example: "0" device: type: string description: Device platform example: "SAFARI" enum: [ "UNKNOWN", "CHROME", "FIREFOX", "IE", "OPERA", "SAFARI", "EDGE", "DESKTOP", "IPAD", "ANDROID_TABLET", "OHANA", "ALOHA", "CATALINA", "TCL_TV", ] server: type: string description: WhatsApp server example: "s.whatsapp.net" ad: type: string description: Full device address example: "5521971532700.0:5@s.whatsapp.net" jid: type: string description: Device JID example: "5521971532700:59@s.whatsapp.net" examples: success_response: summary: Successful response with multiple users value: code: 200 success: true data: users: "5521971532700@s.whatsapp.net": jid: "5521971532700@s.whatsapp.net" status: "" picture_id: "1729003008" is_business_account: false device_count: 4 first_device: "5521971532700@s.whatsapp.net" devices: - user: "5521971532700" agent: "0" device: "UNKNOWN" server: "s.whatsapp.net" ad: "5521971532700.0:0@s.whatsapp.net" jid: "5521971532700@s.whatsapp.net" - user: "5521971532700" agent: "0" device: "SAFARI" server: "s.whatsapp.net" ad: "5521971532700.0:5@s.whatsapp.net" jid: "5521971532700:5@s.whatsapp.net" - user: "5521971532700" agent: "0" device: "UNKNOWN" server: "s.whatsapp.net" ad: "5521971532700.0:66@s.whatsapp.net" jid: "5521971532700:66@s.whatsapp.net" - user: "5521971532700" agent: "0" device: "UNKNOWN" server: "s.whatsapp.net" ad: "5521971532700.0:67@s.whatsapp.net" jid: "5521971532700:67@s.whatsapp.net" "5521979232690@s.whatsapp.net": jid: "5521979232690@s.whatsapp.net" status: "" picture_id: "1728656243" is_business_account: false device_count: 3 first_device: "5521979232690@s.whatsapp.net" devices: - user: "5521979232690" agent: "0" device: "UNKNOWN" server: "s.whatsapp.net" ad: "5521979232690.0:0@s.whatsapp.net" jid: "5521979232690@s.whatsapp.net" - user: "5521979232690" agent: "0" device: "SAFARI" server: "s.whatsapp.net" ad: "5521979232690.0:5@s.whatsapp.net" jid: "5521979232690:5@s.whatsapp.net" - user: "5521979232690" agent: "0" device: "UNKNOWN" server: "s.whatsapp.net" ad: "5521979232690.0:99@s.whatsapp.net" jid: "5521979232690:99@s.whatsapp.net" "400": description: Bad request - invalid payload content: application/json: schema: type: object properties: code: type: integer example: 400 success: type: boolean example: false error: type: string example: "missing phone numbers in payload. Use 'Phone' or 'phone' field" "500": description: Internal server error content: application/json: schema: type: object properties: code: type: integer example: 500 success: type: boolean example: false error: type: string example: "no session" /user/privacy/settings: get: tags: - User summary: Get user privacy settings description: | Retrieves the current privacy settings for the authenticated user including: - Group add permissions - Last seen visibility - Status visibility - Profile photo visibility - Read receipts setting - Online status visibility - Call add permissions All settings return values like: "all", "contacts", "contact_blacklist", "none", "match_last_seen", "known" security: - ApiKeyAuth: [] responses: 200: description: Privacy settings retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: group_add: type: string description: "Who can add you to groups" example: "contacts" last_seen: type: string description: "Who can see your last seen" example: "contacts" status: type: string description: "Who can see your status" example: "contacts" profile: type: string description: "Who can see your profile photo" example: "all" read_receipts: type: string description: "Read receipts setting" example: "all" online: type: string description: "Who can see when you're online" example: "match_last_seen" call_add: type: string description: "Who can call you" example: "all" success: type: boolean example: true example: code: 200 data: group_add: "contacts" last_seen: "contacts" status: "contacts" profile: "all" read_receipts: "all" online: "match_last_seen" call_add: "all" success: true 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/pushname: post: tags: - User summary: Change user push name (display name) description: | Changes the push name (display name) for the authenticated user. This name appears in chats and contact lists for other WhatsApp users. **Important Notes:** - Push name cannot be empty - Changes are synchronized across all devices - May take a few minutes to propagate to all contacts security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ChangePushNameRequest" responses: 200: description: Push name updated successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: success: type: boolean example: true message: type: string example: "Push name updated successfully" push_name: type: string example: "John Doe" success: type: boolean example: true example: code: 200 data: success: true message: "Push name updated successfully" push_name: "John Doe" success: true 400: description: Bad request - push name cannot be empty content: application/json: schema: example: { "error": "push name cannot be empty" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/contact/info: post: tags: - User summary: Get comprehensive contact information description: | Retrieve comprehensive information about a WhatsApp contact by combining data from multiple sources. Accepts a phone number (international format without +), a JID (e.g., 5511999999999@s.whatsapp.net), or a LID (e.g., 123456@lid). **Data Sources Combined:** - **IsOnWhatsApp**: Registration status and verified name - **GetUserInfo**: About/status, picture ID, devices, LID, verified name - **GetProfilePictureInfo**: Avatar URL and direct path - **GetBusinessProfile**: Email, address, categories, business hours - **Store.Contacts**: Cached names (push name, business name, full name) - **Store.LIDs**: LID ↔ phone number mapping **Input Formats:** - Phone number: `5511999999999` (international format without +) - JID: `5511999999999@s.whatsapp.net` - LID: `123456@lid` (will be resolved to phone number first) **Important Notes:** - If a LID is provided, it is resolved to a phone number JID before fetching data - If the number is not registered on WhatsApp, only basic info is returned with null fields - Business profile data is only available for WhatsApp Business accounts - Avatar URL has a temporary expiration and should be consumed promptly security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone properties: phone: type: string description: "Phone number (international format without +), JID (e.g., 5511999999999@s.whatsapp.net), or LID (e.g., 123456@lid)" example: "5511999999999" examples: phone_number: summary: Using phone number value: phone: "5511999999999" jid_format: summary: Using JID value: phone: "5511999999999@s.whatsapp.net" lid_format: summary: Using LID value: phone: "123456@lid" responses: 200: description: Contact information retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: phone: type: string description: Phone number extracted from JID example: "5511999999999" jid: type: string description: Canonical WhatsApp JID example: "5511999999999@s.whatsapp.net" input_type: type: string description: "Type of input provided: phone, jid, or lid" enum: - phone - jid - lid example: "phone" is_on_whatsapp: type: boolean description: Whether the number is registered on WhatsApp example: true verified_name: type: string nullable: true description: Verified business name (if available) example: "My Business" lid: type: string nullable: true description: Linked ID for the contact example: "123456:78@lid" devices: type: array nullable: true description: List of connected devices items: type: object properties: user: type: string example: "5511999999999" agent: type: string example: "0" device: type: string example: "iPhone" server: type: string example: "s.whatsapp.net" ad: type: string example: "5511999999999.0:0@s.whatsapp.net" jid: type: string example: "5511999999999.0:0@s.whatsapp.net" user_info: type: object nullable: true description: User profile information properties: status: type: string description: About/status text example: "Hey there! I am using WhatsApp" picture_id: type: string example: "1234567890" verified_name: type: string nullable: true example: "My Business" is_business_account: type: boolean example: false device_count: type: integer example: 2 avatar: type: object nullable: true description: Profile picture information properties: url: type: string description: Temporary URL for the profile picture example: "https://pps.whatsapp.net/v/t62.123-24/example.jpg" id: type: string example: "1234567890" type: type: string example: "image" direct_path: type: string example: "/v/t62.123-24/example.jpg" contact_names: type: object nullable: true description: Locally cached contact names properties: first_name: type: string example: "João" full_name: type: string example: "João Silva" push_name: type: string example: "João" business_name: type: string example: "" business_profile: type: object nullable: true description: Business profile data (only for business accounts) properties: address: type: string example: "Rua Example, 123" email: type: string example: "contact@business.com" business_hours_timezone: type: string example: "America/Sao_Paulo" categories: type: array items: type: object properties: id: type: string example: "123" name: type: string example: "Shopping & Retail" profile_options: type: object description: Additional business profile options business_hours: type: array items: type: object properties: day_of_week: type: string example: "mon" mode: type: string example: "open_with_hours" open_time: type: string example: "08:00" close_time: type: string example: "18:00" success: type: boolean example: true example: code: 200 data: phone: "5511999999999" jid: "5511999999999@s.whatsapp.net" input_type: "phone" is_on_whatsapp: true verified_name: null lid: "123456:78@lid" devices: - user: "5511999999999" agent: "0" device: "iPhone" server: "s.whatsapp.net" ad: "5511999999999.0:0@s.whatsapp.net" jid: "5511999999999.0:0@s.whatsapp.net" user_info: status: "Hey there! I am using WhatsApp" picture_id: "1234567890" verified_name: null is_business_account: false device_count: 1 avatar: url: "https://pps.whatsapp.net/v/t62.123-24/example.jpg" id: "1234567890" type: "image" direct_path: "/v/t62.123-24/example.jpg" contact_names: first_name: "João" full_name: "João Silva" push_name: "João" business_name: "" business_profile: null success: true 400: description: Bad request - missing or invalid parameters content: application/json: schema: type: object properties: error: type: string examples: missing_phone: value: error: "missing phone in payload" invalid_input: value: error: "invalid phone number, JID, or LID" bad_payload: value: error: "could not decode payload" 404: description: LID could not be resolved to a phone number content: application/json: schema: type: object properties: error: type: string example: "could not resolve LID to phone number. The LID mapping may not be cached locally" 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string examples: no_session: value: error: "no session" whatsapp_check_failed: value: error: "failed to check WhatsApp registration: connection error" lid_store_unavailable: value: error: "LID store not available" /user/contact/add: post: tags: - User summary: Add or update a contact description: | Add a new contact or update an existing contact's full name in WhatsApp. The contact will be saved to the primary address book and synchronized across all devices. **Important Notes:** - Phone number must be in international format without the + prefix (e.g., 5511999999999) - Full name is required and cannot be empty - If contact already exists, the name will be updated - Changes are synchronized across all devices - Uses WhatsApp's app state sync mechanism (BuildContact) **Technical Details:** - Operation: `SyncdMutation_SET` - App State Type: `WAPatchCriticalUnblockLow` - Index Type: `IndexContact` - Saves to primary addressbook automatically security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - full_name properties: phone: type: string description: Phone number in international format without + prefix example: "5511999999999" full_name: type: string description: Full name for the contact example: "João Silva" example: phone: "5511999999999" full_name: "João Silva" responses: 200: description: Contact added successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: success: type: boolean example: true message: type: string example: "Contact added successfully" phone: type: string example: "5511999999999" full_name: type: string example: "João Silva" success: type: boolean example: true example: code: 200 data: success: true message: "Contact added successfully" phone: "5511999999999" full_name: "João Silva" success: true 400: description: Bad request - missing or invalid parameters content: application/json: schema: type: object properties: error: type: string example: "phone number cannot be empty" examples: missing_phone: value: error: "phone number cannot be empty" missing_name: value: error: "full name cannot be empty" invalid_phone: value: error: "could not parse phone number" 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string examples: no_session: value: error: "no session" operation_failed: value: error: "failed to add contact: connection error" /user/contact/remove: post: tags: - User summary: Remove a contact description: | Remove a contact from your WhatsApp address book. The contact will be deleted and synchronized across all devices. **Important Notes:** - Phone number must be in international format without the + prefix (e.g., 5511999999999) - Removing a contact doesn't block them or delete chat history - Changes are synchronized across all devices - Uses WhatsApp's app state sync mechanism (RemoveContact) **Technical Details:** - Operation: `SyncdMutation_REMOVE` - App State Type: `WAPatchCriticalUnblockLow` - Index Type: `IndexContact` - Removes from primary addressbook security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone properties: phone: type: string description: Phone number in international format without + prefix example: "5511999999999" example: phone: "5511999999999" responses: 200: description: Contact removed successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: success: type: boolean example: true message: type: string example: "Contact removed successfully" phone: type: string example: "5511999999999" success: type: boolean example: true example: code: 200 data: success: true message: "Contact removed successfully" phone: "5511999999999" success: true 400: description: Bad request - missing or invalid phone number content: application/json: schema: type: object properties: error: type: string examples: missing_phone: value: error: "phone number cannot be empty" invalid_phone: value: error: "could not parse phone number" 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string examples: no_session: value: error: "no session" operation_failed: value: error: "failed to remove contact: connection error" /user/status: get: tags: - User summary: Get user status message description: | Retrieves the current status message (about text) of the authenticated user. This is the text that appears in the "About" section of the user's profile, different from ephemeral status broadcasts. security: - ApiKeyAuth: [] responses: 200: description: User status retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: status: type: string description: "Current status message/about text" example: "Available for work 💼" success: type: boolean example: true example: code: 200 data: status: "Available for work 💼" success: true 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } post: tags: - User summary: Set user status message description: | Updates the status message (about text) for the authenticated user. This text appears in the "About" section of the user's profile. **Important Notes:** - This is different from ephemeral status broadcasts - The status is visible to contacts based on privacy settings - Changes are synchronized across all devices security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SetMyStatusRequest" responses: 200: description: Status updated successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: success: type: boolean example: true message: type: string example: "Status updated successfully" status: type: string example: "Working from home 🏠" success: type: boolean example: true example: code: 200 data: success: true message: "Status updated successfully" status: "Working from home 🏠" success: true 400: description: Bad request - invalid JSON payload content: application/json: schema: example: { "error": "could not decode payload" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/update: post: tags: - User summary: Update user profile (name and/or token) description: | Allows authenticated users to update their own name and/or authentication token. **Important Security Notes:** - Token is invalidated immediately after change - you must use the new token in subsequent requests - Changing the token will disconnect any active sessions using the old token - Both fields are optional, but at least one must be provided and different from current value - Token changes use optimistic locking to prevent race conditions **Use Cases:** - Change display name for better identification - Rotate authentication token for security purposes - Update both name and token in a single atomic operation **Cache Behavior:** - Old token cache is invalidated immediately - New token cache is pre-populated with complete user configuration - Zero downtime during token transition **Requirements:** - User must be authenticated (token header required) - At least one field (name or token) must be provided - Name: 1-255 characters - Token: minimum 8 characters - Token must be unique across all users security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: New user display name (1-255 characters) minLength: 1 maxLength: 255 example: "John Doe Updated" token: type: string description: New authentication token (minimum 8 characters, must be unique) minLength: 8 example: "new_secure_token_12345678" example: name: "John Doe Updated" token: "new_secure_token_12345678" responses: 200: description: Profile updated successfully content: application/json: schema: type: object properties: code: type: integer example: 200 success: type: boolean example: true data: type: object properties: id: type: string description: User unique identifier example: "bec45bb93cbd24cbec32941ec3c93a12" name: type: string description: Updated user name example: "John Doe Updated" token: type: string description: New authentication token (use this for subsequent requests) example: "new_secure_token_12345678" message: type: string example: "Profile updated successfully" example: code: 200 success: true data: id: "bec45bb93cbd24cbec32941ec3c93a12" name: "John Doe Updated" token: "new_secure_token_12345678" message: "Profile updated successfully" 400: description: Bad request - validation error content: application/json: schema: type: object properties: code: type: integer example: 400 success: type: boolean example: false error: type: string example: "Name cannot be empty" examples: emptyName: value: code: 400 success: false error: "Name cannot be empty" noChanges: value: code: 400 success: false error: "No changes detected" tokenTooShort: value: code: 400 success: false error: "Token too short (min 8 characters)" nameTooLong: value: code: 400 success: false error: "Name too long (max 255 characters)" invalidJson: value: code: 400 success: false error: "Invalid JSON" 401: description: Unauthorized - user token required content: application/json: schema: type: object properties: error: type: string example: "unauthorized" 409: description: Conflict - token already in use or concurrent modification content: application/json: schema: type: object properties: code: type: integer example: 409 success: type: boolean example: false error: type: string example: "Token already in use" examples: tokenInUse: value: code: 409 success: false error: "Token already in use" concurrentModification: value: code: 409 success: false error: "Profile was modified by another request. Please try again" 500: description: Internal server error content: application/json: schema: type: object properties: code: type: integer example: 500 success: type: boolean example: false error: type: string example: "Failed to update profile: database error" /user/business/profile: post: tags: - User summary: Get business profile information description: | Retrieves detailed business profile information for WhatsApp Business accounts including: - Business email and address - Business categories - Operating hours with timezone - Profile options and settings **Note:** This endpoint only works for WhatsApp Business accounts. Regular personal accounts will return an error. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/BusinessProfileRequest" responses: 200: description: Business profile retrieved successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: jid: type: string example: "5491155553934@s.whatsapp.net" email: type: string example: "business@company.com" address: type: string example: "123 Business Street, City, Country" categories: type: array items: type: object properties: id: type: string example: "PROFESSIONAL_SERVICES" name: type: string example: "Professional Services" profile_options: type: object additionalProperties: type: string example: website: "https://company.com" about: "We provide excellent services" business_hours_timezone: type: string example: "America/Argentina/Buenos_Aires" business_hours: type: array items: type: object properties: day_of_week: type: string example: "MONDAY" mode: type: string example: "OPEN" open_time: type: string example: "09:00" close_time: type: string example: "18:00" success: type: boolean example: true example: code: 200 data: jid: "5491155553934@s.whatsapp.net" email: "business@company.com" address: "123 Business Street, Buenos Aires, Argentina" categories: - id: "PROFESSIONAL_SERVICES" name: "Professional Services" - id: "CONSULTING" name: "Business Consulting" profile_options: website: "https://company.com" about: "We provide excellent professional services" business_hours_timezone: "America/Argentina/Buenos_Aires" business_hours: - day_of_week: "MONDAY" mode: "OPEN" open_time: "09:00" close_time: "18:00" - day_of_week: "FRIDAY" mode: "OPEN" open_time: "09:00" close_time: "17:00" success: true 400: description: Bad request - missing or invalid phone number content: application/json: schema: example: { "error": "missing phone number in payload" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/check: post: tags: - User summary: Checks if user has WhatsApp description: Checks if users have an account with WhatsApp security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/Checkuser" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Users": [ { "IsInWhatsapp": true, "JID": "5491155553934@s.whatsapp.net", "Query": "5491155553934", "VerifiedName": "Company Name", }, { "IsInWhatsapp": false, "JID": "5521971532700@s.whatsapp.net", "Query": "5521971532700", "VerifiedName": "", }, ], }, "success": true, } /user/presence: post: tags: - User summary: Send user global presence description: Sends user presence Available or Unavailable security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UserPresence" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Presence set successfuly" }, "success": true, } 400: description: Response content: application/json: schema: example: { "code": 400, "error": "Invalid presence type. Allowed values: 'available', 'unavailable'", "success": false, } /user/avatar: post: tags: - User summary: Gets profile picture information description: | Gets information about users profile pictures on WhatsApp, either a thumbnail (Preview=true) or full picture. **Advanced Features:** - **CommonGID**: Get profile pictures of users through a shared group, bypassing some privacy restrictions - **InviteCode**: Preview group profile pictures before joining using an invite code - **PersonaID**: Retrieve profile pictures of Meta AI bots - **IsCommunity**: Specify when querying Community profile pictures All advanced parameters are optional and maintain full backward compatibility. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/Checkavatar" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "direct_path": "/v/t61.24694-24/462747675_396645986828450_4384832977029011659_n.jpg?stp=dst-jpg_s96x96_tt6&ccb=11-4&oh=01_Q5Aa1wGBFw0hNQaFWtrLrS0BPrIrq6hN0w96ytplsv7__yI42g&oe=68565151&_nc_sid=5e03e0&_nc_cat=107", "id": "1729003008", "type": "preview", "url": "https://pps.whatsapp.net/v/t61.24694-24/462747675_396645986828450_4384832977029011659_n.jpg?stp=dst-jpg_s96x96_tt6&ccb=11-4&oh=01_Q5Aa1wGBFw0hNQaFWtrLrS0BPrIrq6hN0w96ytplsv7__yI42g&oe=68565151&_nc_sid=5e03e0&_nc_cat=107", }, "success": true, } /user/photo: post: tags: - User summary: Set profile photo operationId: setMyProfilePhoto description: | Set or update the authenticated user's own WhatsApp profile photo. **Accepted input formats:** - **Base64 data URL**: `"data:image/jpeg;base64,/9j/4AAQ..."` — inline JPEG encoded as data URL - **HTTP/HTTPS URL**: `"https://example.com/photo.jpg"` — remote image URL (will be downloaded server-side) **Image requirements:** - **Format**: JPEG only (`.jpg` / `.jpeg`). Other formats (PNG, GIF, WebP) are **not accepted** by WhatsApp and will be rejected - **Maximum resolution**: 640x640 pixels (images larger than this may be rejected by WhatsApp) - **Minimum resolution**: No strict minimum, but very small images may appear pixelated - **File size**: No strict limit, but recommended under 5MB for optimal processing - **Aspect ratio**: Square (1:1) is recommended. Non-square images may be cropped by WhatsApp clients **How it works internally:** Uses the WhatsApp `w:profile:picture` IQ namespace with an empty JID target, which tells the server to update the authenticated user's own profile picture rather than a group photo. **Important Notes:** - Changes propagate to all contacts immediately - The previous profile photo is replaced (not archived) - To remove the photo entirely, use the `/user/photo/remove` endpoint security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SetProfilePhoto" examples: base64: summary: Base64 data URL value: Image: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..." url: summary: Remote URL value: Image: "https://example.com/my-profile-photo.jpg" responses: 200: description: Profile photo set successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: Details: type: string example: "Profile photo set successfully" PictureID: type: string description: "Unique identifier assigned to the new profile picture by WhatsApp" example: "1729003008" success: type: boolean example: true example: code: 200 data: Details: "Profile photo set successfully" PictureID: "1729003008" success: true 400: description: Bad request - invalid image format, missing field, or download failure content: application/json: schema: type: object properties: code: type: integer example: 400 data: type: string success: type: boolean example: false examples: missing_image: summary: Missing Image field value: code: 400 data: "missing Image in Payload" success: false not_jpeg: summary: Image is not JPEG value: code: 400 data: "image must be in JPEG format. WhatsApp only accepts JPEG images for profile photos" success: false invalid_input: summary: Invalid input format value: code: 400 data: 'Image must be a base64 data URL ("data:image/jpeg;base64,...") or an HTTP/HTTPS URL' success: false download_failed: summary: Remote URL download failed value: code: 400 data: "could not download image from URL: HTTP error 404 when downloading from URL" success: false decode_failed: summary: Base64 decode failed value: code: 400 data: "could not decode base64 encoded data from payload" success: false 500: description: Internal server error - no active session or WhatsApp rejected the image content: application/json: schema: type: object properties: code: type: integer example: 500 data: type: string success: type: boolean example: false examples: no_session: summary: No active WhatsApp session value: code: 500 data: "no session" success: false whatsapp_rejected: summary: WhatsApp rejected the image value: code: 500 data: "failed to set profile photo: image not acceptable" success: false /user/photo/remove: post: tags: - User summary: Remove profile photo operationId: removeMyProfilePhoto description: | Remove the authenticated user's own WhatsApp profile photo. After removal, the profile will display the default WhatsApp placeholder avatar (grey silhouette). **Important Notes:** - This action is immediate and irreversible (the previous photo is permanently deleted from WhatsApp servers) - All contacts will see the default placeholder avatar - No request body is required security: - ApiKeyAuth: [] responses: 200: description: Profile photo removed successfully content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: object properties: Details: type: string example: "Profile photo removed successfully" success: type: boolean example: true example: code: 200 data: Details: "Profile photo removed successfully" success: true 500: description: Internal server error - no active session or WhatsApp error content: application/json: schema: type: object properties: code: type: integer example: 500 data: type: string success: type: boolean example: false examples: no_session: summary: No active WhatsApp session value: code: 500 data: "no session" success: false removal_failed: summary: WhatsApp error during removal value: code: 500 data: "failed to remove profile photo: connection closed" success: false /user/contacts: get: tags: - User summary: Gets all contacts for the account description: Gets complete list of contacts for the connected account security: - ApiKeyAuth: [] responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "5511999999999@s.whatsapp.net": { "BusinessName": "", "FirstName": "", "Found": true, "FullName": "", "PushName": "FOP2", }, "5511888888888@s.whatsapp.net": { "BusinessName": "", "FirstName": "", "Found": true, "FullName": "", "PushName": "Digitalsac Software Engineering", }, }, } /user/lid/get: get: tags: - User LID summary: Get LID from Phone/JID (GET) description: Convert a phone number or JID to its corresponding LID (Link ID) format using GET method with query parameter security: - ApiKeyAuth: [] parameters: - name: phone in: query required: true description: Phone number or JID to convert to LID schema: type: string example: "5521971532700@s.whatsapp.net" responses: 200: description: Successfully retrieved LID information content: application/json: schema: $ref: "#/definitions/LIDResponse" 400: description: Invalid phone/JID format content: application/json: schema: example: { "error": "invalid phone/JID format" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } post: tags: - User LID summary: Get LID from Phone/JID (POST) description: Convert a phone number or JID to its corresponding LID (Link ID) format using POST method with JSON payload security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GetLIDRequest" responses: 200: description: Successfully retrieved LID information content: application/json: schema: $ref: "#/definitions/LIDResponse" 400: description: Invalid phone/JID format content: application/json: schema: example: { "error": "invalid phone/JID format" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/lid/from-lid: get: tags: - User LID summary: Get Phone/JID from LID (GET) description: Convert a LID (Link ID) to its corresponding phone number or JID using GET method with query parameter security: - ApiKeyAuth: [] parameters: - name: lid in: query required: true description: LID to convert to phone/JID schema: type: string example: "2:abcd1234efgh5678@lid" responses: 200: description: Successfully retrieved phone/JID information content: application/json: schema: $ref: "#/definitions/JIDFromLIDResponse" 400: description: Invalid LID format content: application/json: schema: example: { "error": "invalid LID format" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } post: tags: - User LID summary: Get Phone/JID from LID (POST) description: Convert a LID (Link ID) to its corresponding phone number or JID using POST method with JSON payload security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GetJIDFromLIDRequest" responses: 200: description: Successfully retrieved phone/JID information content: application/json: schema: $ref: "#/definitions/JIDFromLIDResponse" 400: description: Invalid LID format content: application/json: schema: example: { "error": "invalid LID format" } 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /user/lid/mappings: get: tags: - User LID summary: List LID Mappings description: List all LID (Link ID) mappings for the authenticated user, showing the relationship between phone numbers/JIDs and their corresponding LIDs security: - ApiKeyAuth: [] parameters: - name: limit in: query required: false description: Maximum number of mappings to return (default 100) schema: type: integer default: 100 example: 50 - name: offset in: query required: false description: Number of mappings to skip for pagination (default 0) schema: type: integer default: 0 example: 0 responses: 200: description: Successfully retrieved LID mappings content: application/json: schema: $ref: "#/definitions/LIDMappingsResponse" 500: description: Internal server error content: application/json: schema: example: { "error": "no session" } /chat/delete: post: tags: - Chat summary: Deletes a message sent by user description: Deletes a messages sent by the same user security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DeleteMessage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Message deleted" }, "success": true, } /chat/markread: post: tags: - Chat summary: Marks a message as read description: Marks one or more received messages as read security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/Markread" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Message(s) marked as read" }, "success": true, } /chat/react: post: tags: - Chat summary: Reacts to a message description: Sends a reaction to some message. Phone, Body and Id are mandatory. If reaction is for your own message, prefix Phone with 'me:'. Body should be the reaction emoji. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ReactionText" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "3EB06F9067F80BAB89FF", "Timestamp": "2022-05-10T12:49:08-03:00", }, "success": true, } /chat/send/text: post: tags: - Send summary: Sends a text message description: | Sends a text message. Phone and Body are mandatory. If no Id is supplied, a random one will be generated. **Reply Support (ContextInfo):** ContextInfo is optional and used when replying to a message. Required fields for replies: - `stanzaID`: The message ID you are replying to - `participant`: JID of who wrote the original message **Full Reply Preview (quotedMessage):** For proper reply preview display on all devices, include `quotedMessage` with the original message content: ```json { "Phone": "5511999999999", "Body": "My reply", "ContextInfo": { "stanzaID": "ABC123DEF456", "participant": "5511888888888@s.whatsapp.net", "quotedMessage": { "conversation": "Original message text being replied to" } } } ``` Without `quotedMessage`, replies will work but may not show the original message preview correctly on devices. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageText" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/link: post: tags: - Send summary: Send a link message with automatic preview from metadata. description: Send a link message with automatic preview from metadata. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageLink" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/edit: post: tags: - Send summary: Edit an existing message description: | Edits the content of a previously sent message. Only text messages can be edited and only within 15 minutes of sending. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageEdit" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Message edited successfully", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", }, "success": true, } /chat/send/image: post: tags: - Send summary: Sends an image/picture message description: Sends an image message. Supports both base64 encoded data (image/png or image/jpeg formats) and HTTP(S) URLs pointing to image files. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/audio: post: tags: - Send summary: Sends an audio message description: Sends an audio message. Supports both base64 encoded data (opus format, mime type audio/ogg) and HTTP(S) URLs pointing to audio files. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageAudio" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/document: post: tags: - Send summary: Sends a document message description: Sends any document. Supports both base64 encoded data (application/octet-stream mime) and HTTP(S) URLs pointing to document files. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageDocument" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/video: post: tags: - Send summary: Sends a video message description: Sends a video message. Supports both base64 encoded data (video/mp4 or video/3gpp format) and HTTP(S) URLs pointing to video files. Only H.264 video codec and AAC audio codec is supported. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageVideo" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/ptv: post: tags: - Send summary: Send PTV (Pre-Recorded Transfer Video) description: Send a PTV by link or base64 (data URL). Only requires phone and video. PTV messages are sent as pre-recorded video. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessagePTV" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/sticker: post: tags: - Send summary: Sends a sticker message description: Sends a sticker message. Supports both base64 encoded data (image/webp format) and HTTP(S) URLs pointing to sticker files. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageSticker" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/location: post: tags: - Send summary: Sends a location message description: Sends a location message security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageLocation" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/contact: post: tags: - Send summary: Sends a contact message description: Sends a contact message in VCARD format security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageContact" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/list: post: tags: - Send summary: Sends a List message description: Sends a List message security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageList" examples: product_menu: summary: "Catálogo de Produtos" description: "Lista interativa com seções e itens" value: Phone: "5521979232690" Title: "Catálogo 2024" Text: "Confira nossos destaques do mês" Footer: "Escolha uma opção abaixo" ButtonText: "Ver opções" Sections: - Title: "Planos Disponíveis" Rows: - RowId: "plan_basic" Title: "Plano Basic" Description: "Ideal para pequenas equipes" - RowId: "plan_pro" Title: "Plano Pro" Description: "Recursos avançados e suporte prioritário" - Title: "Serviços Adicionais" Rows: - RowId: "service_consulting" Title: "Consultoria" Description: "Sessões 1:1 com especialistas" - RowId: "service_training" Title: "Treinamentos" Description: "Workshops personalizados para equipes" restaurant_menu: summary: "Lista de Restaurante" description: "Exemplo com seções de menu e itens" value: Phone: "120363312246943103@g.us" Title: "Menu Especial da Semana" Text: "Selecione a opção desejada abaixo" Footer: "Atendimento das 11h às 23h" ButtonText: "Escolher prato" Sections: - Title: "Entradas" Rows: - RowId: "entrada_01" Title: "Bruschetta" Description: "Tomate, manjericão e azeite" - RowId: "entrada_02" Title: "Carpaccio" Description: "Finas lâminas de carne ao molho" - Title: "Pratos Principais" Rows: - RowId: "principal_01" Title: "Risoto de Camarão" Description: "Arroz arbóreo e camarões grelhados" - RowId: "principal_02" Title: "Filé ao Molho Madeira" Description: "Acompanhado de batatas gratinadas" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/poll: post: tags: - Send summary: Sends a Poll to some group description: Sends a Poll message. Group should contain the gid (group id), similar to 120363312246943103@g.us. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessagePoll" examples: group_poll: summary: "Enquete em Grupo" description: "Exemplo com envio para grupo" value: Group: "120363312246943103@g.us" Header: "Qual o melhor horário?" Options: - "09:00" - "14:00" - "19:00" MaxAnswer: 2 Presence: 2000 NumberCheck: true direct_poll: summary: "Enquete 1:1" description: "Envio direto para um contato com pergunta personalizada" value: Phone: "5521979232690" Question: "Você recomenda nosso atendimento?" Options: - "Sim" - "Talvez" - "Não" MaxAnswer: 1 Duration: 86400 responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Poll sent successfully", "Id": "90B2F8B13FAC8A9CF6B06E99C7834DC5", }, "success": true, } /chat/send/event: post: tags: - Send summary: Send event message description: | Send calendar event invitation with date, time, location, and description to a WhatsApp contact or group. Recipients can add the event to their calendar. Perfect for meetings, appointments, conferences, and scheduled calls. **Features:** - **Event Details**: Name, description, start/end times - **Location Support**: GPS coordinates and address - **Call Integration**: Schedule video/voice meetings - **Guest Management**: Allow additional guests - **Cancellation**: Mark events as cancelled - **Message Enhancements**: Replies, forwarding, mentions, expiration **Use Cases:** - 📅 Meeting invitations - 🎉 Event planning (parties, conferences) - 📞 Scheduled calls - 🏢 Location-based events - ❌ Event cancellations security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/MessageEvent" examples: business_meeting: summary: "Business Meeting" description: "Schedule a business meeting with location" value: Phone: "5521971532700" Name: "Weekly Team Sync 📅" Description: "Discussion of project updates, blockers, and next steps" StartTime: 2524608000 EndTime: 2556143999 ExtraGuestsAllowed: true IsScheduleCall: true Location: Name: "Conference Room A, Main Office" DegreesLatitude: -23.5505 DegreesLongitude: -46.6333 NumberCheck: true ContextInfo: MentionedJID: ["5521971532700@s.whatsapp.net"] virtual_event: summary: "Virtual Event" description: "Online event without physical location" value: Phone: "120363312246943103@g.us" Name: "Product Launch Event 🚀" Description: "Join us for the launch of our new product line" StartTime: 1703184000 EndTime: 1703191200 ExtraGuestsAllowed: true IsScheduleCall: true MentionInfo: MentionAll: true responses: 200: description: Event message sent successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "EVENT_90B2F8B13FAC8A9CF6B06E99C7834DC5", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/buttons: post: tags: - Send summary: Send interactive buttons message description: | Send an interactive message with buttons to a WhatsApp contact or group. Supports multiple button types and media headers. **⚠️ IMPORTANTE - Campos de Texto (case canonical):** - Payloads devem usar `lowerCamelCase` (ex.: `buttonId`, `displayText`) e, quando aplicável, campos snake_case opcionais como `pix_key`. - Quando usar **media header** (`image`/`video`/`document`): forneça o conteúdo principal no campo `caption` ou `text`. - Quando **não** houver media: utilize `text` ou `body`. Os handlers fazem mirror automático entre ambos. - Exemplos com media usam `text` para manter compatibilidade com o backend. **Supported Button Types:** - 🔘 **reply/quick_reply** – botão de resposta rápida (retorna `buttonId`) - 🔗 **url/cta_url** – abre um link HTTP(S) (`url` ou `merchant_url`) - 📞 **call/cta_call** – inicia uma chamada de voz (`phone` em formato E.164) - 📋 **copy/cta_copy** – copia um código (`code`) - 💰 **pix/payment_info** – botão de pagamento PIX (`pix_key`, `merchant_name`, `pix_type`, ...) - 💳 **review_and_pay** – revisão/pagamento com lista de itens (`items[]`) **Media Header Support:** - 🖼️ `image` – exibe imagem acima dos botões (`image.url` obrigatório) - 🎥 `video` – exibe vídeo curto (`video.url`) - 📄 `document` – exibe documento (`document.url`) **Button Configuration:** Cada botão requer `buttonId`, `buttonText.displayText` e `type`. Campos adicionais variam conforme o tipo: - **url/cta_url**: `url` ou `merchant_url` - **call/cta_call**: `phone` - **copy/cta_copy**: `code` - **pix/payment_info**: `pix_key`, `merchant_name`, `pix_type`, `currency`, `total_value`, `total_offset` - **review_and_pay**: `reference_id` e `items[]` com `name`, `quantity`, `amount_value`, `amount_offset` **Payment Items Structure** (`review_and_pay`): Cada item deve informar `name`, `quantity`, `amount_value`, `amount_offset`. **Text Fields:** - **title**: Título principal (opcional) - **text/body**: Conteúdo da mensagem (obrigatório quando não há media) - **footer**: Texto secundário (opcional) - **caption**: Usado como corpo ao enviar media security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ButtonsMessage" examples: pix_payment: summary: "PIX" description: "Botão PIX usando payload camelCase/snake_case compatível com a API." value: phone: "5521979232690" title: "Pagamento PIX" body: "Escaneie o QR Code para pagar via PIX" footer: "Pagamento seguro e instantâneo" buttons: - buttonId: "pix_btn_1" buttonText: displayText: "Pagar com PIX" type: "pix" pix_key: "11999999999" merchant_name: "Minha Loja" pix_type: "PHONE" review_and_pay: summary: "Review and Pay" description: "Exemplo completo com lista de itens, utilizando os campos esperados pelo backend." value: phone: "5521979232690" title: "Revise seu pedido" text: "Confirme os itens antes de pagar" footer: "Envio em até 24h após confirmação" buttons: - buttonId: "review_pay_btn" buttonText: displayText: "Revisar e pagar" type: "review_and_pay" pix_key: "11999999999" merchant_name: "Minha Loja" pix_type: "PHONE" currency: "BRL" total_value: 10990 total_offset: 100 reference_id: "ORDER-2024-001" items: - name: "Fone de ouvido" quantity: 1 amount_value: 7990 amount_offset: 100 - name: "Cabo USB-C" quantity: 1 amount_value: 1990 amount_offset: 100 - name: "Frete expresso" quantity: 1 amount_value: 1000 amount_offset: 100 pix_with_pdf: summary: "PIX com Fatura PDF" description: | Botão review_and_pay com documento PDF no header - ideal para faturas, boletos e cobranças. O PDF aparece como anexo e o botão permite pagamento instantâneo via PIX. Tipos de pix_type suportados: CPF, CNPJ, EMAIL, PHONE, EVP (chave aleatória). value: phone: "5521979232690" title: "Fatura Mensal" text: "Sua fatura está disponível. Pague via PIX." footer: "Vencimento: 15/01/2025" document: url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" buttons: - buttonId: "pix_invoice_1" buttonText: displayText: "Pagar Fatura" type: "review_and_pay" pix_key: "empresa@dominio.com.br" merchant_name: "Empresa LTDA" pix_type: "EMAIL" currency: "BRL" total_value: 29990 total_offset: 100 reference_id: "FAT-2025-01-001" items: - name: "Mensalidade Janeiro/2025" quantity: 1 amount_value: 24990 amount_offset: 100 - name: "Taxa de serviço" quantity: 1 amount_value: 5000 amount_offset: 100 pix_evp: summary: "PIX com Chave Aleatória (EVP)" description: | Botão PIX payment_info com chave aleatória EVP - ideal para pagamentos únicos. EVP (End-to-End Virtual Payment Address) é a chave aleatória gerada pelo banco. value: phone: "5521979232690" title: "Pagamento PIX" body: "Copie a chave PIX e pague no app do seu banco" footer: "Pagamento seguro e instantâneo" buttons: - buttonId: "pix_evp_1" buttonText: displayText: "Copiar Chave PIX" type: "pix" pix_key: "123e4567-e89b-12d3-a456-426614174000" merchant_name: "Minha Loja" pix_type: "EVP" video_cta_url: summary: "Vídeo com botão CTA" description: "Equivalente ao cURL de demonstração de produto." value: phone: "5521979232690" title: "Demonstração do Produto" text: "Assista ao vídeo e compre!" footer: "Pagamento instantâneo" video: url: "https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4" buttons: - buttonId: "cta_url_1" buttonText: displayText: "Abrir Site" type: "cta_url" url: "https://exemplo.com/oferta" document_cta_url: summary: "Catálogo em PDF" description: "Download de catálogo com botão CTA URL." value: phone: "5521979232690" title: "Catálogo de Produtos" text: "Baixe nosso catálogo" footer: "PDF com todos os produtos" document: url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" buttons: - buttonId: "cta_url_1" buttonText: displayText: "Abrir Site" type: "cta_url" url: "https://exemplo.com/oferta" image_quick_reply: summary: "Imagem com resposta rápida" description: "Confirmação de presença usando quick reply." value: phone: "5521979232690" title: "Confirme sua presença" text: "Evento VIP em 12/10 às 20h" footer: "Responda abaixo" image: url: "https://picsum.photos/600/400.jpg" buttons: - buttonId: "reply_talvez" buttonText: displayText: "Talvez" type: "quick_reply" multi_action: summary: "Copy + URL + Call" description: "Mescla de diferentes tipos de botões interativos." value: phone: "5521979232690" title: "Ofertas do Dia" text: "Escolha uma ação abaixo:" footer: "Equipe DigiGO" buttons: - buttonId: "cta_copy_1" buttonText: displayText: "Copiar Cupom" type: "cta_copy" code: "CUPOM123" - buttonId: "cta_url_1" buttonText: displayText: "Abrir Site" type: "cta_url" url: "https://exemplo.com/oferta" - buttonId: "cta_call_1" buttonText: displayText: "Falar com Vendas" type: "cta_call" phone: "+5511988888888" responses: 200: description: Buttons message sent successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "BUTTONS_8A7B9C2D1E3F4A5B6C7D8E9F0A1B2C3D", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/flow: post: tags: - Send summary: Send native flow interactive message description: | Send a native WhatsApp Flow interactive message with custom parameters and flow versioning support. **What are WhatsApp Flows:** Native interactive forms and experiences within WhatsApp chat. Flows allow collecting structured data, multi-step processes, and rich interactive experiences without leaving WhatsApp. **Flow Message Structure:** - **Body/Text/Message**: Main message text (required, at least one of these fields) - **Header**: Optional header with title, subtitle, and media - **Footer**: Optional footer text - **Buttons**: Array of flow buttons with parameters **Header Configuration:** - **Title**: Main header title - **Subtitle**: Secondary header text - **Media**: Media object with type (image/video/document), Url, Caption, Filename, MimeType **Button Configuration:** Each button requires: - **Name**: Button name/identifier - **ButtonParams** or **ButtonParamsJSON**: Button parameters as object or JSON string - **Params** or **ParamsJSON**: Flow parameters as object or JSON string **Flow Parameters:** - **MessageVersion**: Flow message format version (1, 2, 3, etc.) - **MessageParams** or **MessageParamsJSON**: Flow-specific parameters **Common Use Cases:** - 📋 Data collection forms (surveys, registrations) - 🛒 Product catalogs with selections - 📅 Appointment booking flows - 💳 Payment collection forms - 📝 Multi-step applications - ✅ Order confirmations with options **Advanced Features:** - Context info for replying to messages - Mention support for tagging users - Forward info for message forwarding - Presence and duration control - Number validation before sending security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/FlowMessage" examples: simple_flow: summary: "Simple Flow Message" description: "Basic flow with single button" value: Phone: "5521971532700" Body: "Complete your profile to get started" Footer: "Powered by FlowAPI" Buttons: - Name: "complete_profile" ButtonParams: display_text: "Complete Profile" flow_id: "123456789" flow_token: "ABC123XYZ" Params: mode: "draft" version: "3.0" flow_with_header: summary: "Flow with Media Header" description: "Flow message with image header" value: Phone: "5521971532700" Header: Title: "Customer Survey 📊" Subtitle: "Help us improve" Media: Type: "image" Url: "https://example.com/survey-banner.jpg" Caption: "Your feedback matters" Body: "Take 2 minutes to share your experience" Footer: "All responses are confidential" Buttons: - Name: "start_survey" ButtonParams: display_text: "Start Survey" flow_id: "987654321" flow_token: "SURVEY2024" Params: mode: "published" version: "3.0" appointment_flow: summary: "Appointment Booking Flow" description: "Multi-step appointment booking" value: Phone: "120363312246943103@g.us" Body: "Book your appointment with our specialist team" Footer: "Available slots updated in real-time" MessageVersion: 3 Buttons: - Name: "book_appointment" ButtonParamsJSON: '{"display_text":"📅 Book Now","flow_id":"555111222","flow_token":"APPT2024"}' ParamsJSON: '{"mode":"published","flow_name":"Appointment Booking","version":"3.0"}' data_collection: summary: "Data Collection Form" description: "Structured data collection flow" value: Phone: "5521971532700" Header: Title: "Registration Form 📝" Subtitle: "Quick and easy signup" Body: "Complete your registration in just a few steps" Footer: "Your data is encrypted and secure" MessageVersion: 3 MessageParams: flow_type: "registration" required_fields: ["name", "email", "phone"] optional_fields: ["company", "role"] Buttons: - Name: "start_registration" ButtonParams: display_text: "Start Registration" flow_id: "REG123456" flow_token: "TOKEN_REG_2024" Params: mode: "published" version: "3.0" data_schema: "registration_v1" responses: 200: description: Flow message sent successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "FLOW_1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } /chat/send/carousel: post: tags: - Send summary: Send carousel message with multiple cards description: | Send a carousel message containing multiple scrollable cards. Each card can include media (image, video, document), text content, and interactive buttons. Perfect for product showcases, service catalogs, and multi-option presentations. **Carousel Structure:** - **Phone**: Recipient phone number or group JID (required) - **Message**: Introductory message text before carousel (required) - **Carousel**: Array of card objects (required, at least 1 card) **Card Structure:** Each card can contain: - **Text**: Card body text (required) - **MediaUrl**: URL or base64 data URL for media (optional) - **MediaType**: Type of media - image, video, or document (required if MediaUrl provided) - **Filename**: Document filename (optional, for documents) - **Caption**: Media caption text (optional) - **Buttons**: Array of button objects (required) **Button Types:** - 🔘 **reply** - Quick reply button (id + label) - 🔗 **url** - Opens web link (url + label) - 📋 **copy** - Copies code to clipboard (id as code + label) - 📞 **call** - Initiates phone call (id as phone + label) **Button Structure:** - **Id**: Button identifier (for reply/copy) or phone number (for call) - **Label**: Button display text - **Url**: Destination URL (for url type buttons) - **Type**: Button type (reply, url, copy, call) **Media Support:** - **Images**: JPEG, PNG, WebP (recommended max 5MB) - **Videos**: MP4, 3GP (recommended max 16MB, max 90 seconds) - **Documents**: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT **Common Use Cases:** - 🛍️ Product catalogs with images and buy buttons - 🏨 Hotel room options with photos and booking links - 🍕 Restaurant menu with dishes and order buttons - 🎓 Course offerings with descriptions and enrollment - 🏢 Service packages with pricing and contact options - 📱 Feature comparisons with specifications **Best Practices:** - Use 2-10 cards per carousel (optimal user experience) - Keep card text concise (50-100 characters recommended) - Use high-quality images (at least 800x600px) - Limit to 1-3 buttons per card - Maintain consistent card structure throughout carousel **Advanced Features:** - Context info for replying to messages - Mention support for tagging users - Forward info for message forwarding - Presence and duration control - Number validation before sending security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CarouselMessage" examples: product_catalog: summary: "Product Catalog" description: "E-commerce product showcase with images" value: Phone: "5521971532700" Message: "Check out our featured products! 🛍️" Carousel: - Text: "Premium Wireless Headphones 🎧\n\n• Noise cancellation\n• 30h battery\n• Premium sound\n\n$299.99" MediaUrl: "https://picsum.photos/600/400.jpg" MediaType: "image" Caption: "Best Seller!" Buttons: - Id: "buy_headphones" Label: "🛒 Buy Now" Url: "https://store.example.com/headphones" Type: "url" - Id: "headphones_details" Label: "ℹ️ Details" Type: "reply" - Text: "Smart Watch Pro ⌚\n\n• Fitness tracking\n• Heart rate monitor\n• Water resistant\n\n$199.99" MediaUrl: "https://picsum.photos/600/400.jpg" MediaType: "image" Caption: "New Arrival!" Buttons: - Id: "buy_watch" Label: "🛒 Buy Now" Url: "https://store.example.com/watch" Type: "url" - Id: "watch_details" Label: "ℹ️ Details" Type: "reply" - Text: "Bluetooth Speaker 🔊\n\n• 360° sound\n• 12h battery\n• Portable design\n\n$79.99" MediaUrl: "https://picsum.photos/600/400.jpg" MediaType: "image" Caption: "Hot Deal!" Buttons: - Id: "buy_speaker" Label: "🛒 Buy Now" Url: "https://store.example.com/speaker" Type: "url" - Id: "speaker_details" Label: "ℹ️ Details" Type: "reply" video_carousel: summary: "Video Carousel" description: "Product demos with video previews" value: Phone: "5521971532700" Message: "Watch our product demonstrations! 🎥" Carousel: - Text: "Product Setup Tutorial\n\nLearn how to set up your new device in under 5 minutes" MediaUrl: "https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4" MediaType: "video" Caption: "Quick Setup Guide" Buttons: - Id: "PDF_MANUAL_123" Label: "📋 Copy Manual Code" Type: "copy" - Id: "full_tutorial" Label: "🎬 Full Tutorial" Url: "https://youtube.com/watch?v=example" Type: "url" - Text: "Advanced Features Demo\n\nDiscover pro tips and hidden features" MediaUrl: "https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4" MediaType: "video" Caption: "Pro Tips" Buttons: - Id: "features_guide" Label: "📖 Feature Guide" Type: "reply" responses: 200: description: Carousel message sent successfully content: application/json: schema: example: { "code": 200, "data": { "Details": "Sent", "Id": "CAROUSEL_7C8D9E0F1A2B3C4D5E6F7G8H9I0J1K2L", "Timestamp": "2022-04-20T12:49:08-03:00", }, "success": true, } 400: description: Bad request - invalid input content: application/json: schema: example: { "code": 400, "error": "Missing required field: Name or StartTime", "success": false, } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "no session", "success": false } /chat/downloadimage: post: tags: - Chat summary: Downloads Image from message description: Downloads an Image from a message and returns it Base64 media encoded security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DownloadImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Data": "data:image/jpeg;base64,iVBORw0KGgoA5CYII...=", "Mimetype": "image/jpeg", }, "success": true, } /chat/downloadvideo: post: tags: - Chat summary: Downloads Video from message description: Downloads a Video from a message and returns it Base64 media encoded security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DownloadImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Data": "data:video/mp4;base64,iVBORw0KGgoA5CYII...=", "Mimetype": "video/mp4", }, "success": true, } /chat/downloaddocument: post: tags: - Chat summary: Downloads Document from message description: Downloads a Document from a message and returns it Base64 media encoded security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DownloadImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Data": "data:application/pdf;base64,iVBORw0KGgoA5CYII...=", "Mimetype": "application/pdf", }, "success": true, } /chat/downloadaudio: post: tags: - Chat summary: Downloads Audio from message description: Downloads an Audio file from a message and returns it Base64 media encoded security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DownloadImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Data": "data:audio/ogg;base64,T2dnUwACAAAAAAA...=", "Mimetype": "audio/ogg", }, "success": true, } /chat/downloadsticker: post: tags: - Chat summary: Downloads Sticker from message description: Downloads a Sticker from a message and returns it Base64 media encoded security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DownloadImage" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Data": "data:image/webp;base64,UklGRroBAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=", "Mimetype": "image/webp", }, "success": true, } /chat/presence: post: tags: - Chat summary: Sets chat presence description: Sends indication if you are writing or not (state could be either "composing" or "paused"). Optional Media can be set to "audio" for indicating recording a message security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ChatPresence" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Chat presence set successfuly" }, "success": true, } /chat/pin: post: tags: - Chat summary: Pin or unpin a chat description: Pins or unpins a chat in the conversation list. Pinned chats appear at the top of the chat list. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - pin properties: phone: type: string description: Phone number or group JID example: "5491155553333" pin: type: boolean description: True to pin, false to unpin example: true responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Chat pinned successfully", "jid": "5491155553333@s.whatsapp.net", "pinned": true, }, "success": true, } /chat/archive: post: tags: - Chat summary: Archive or unarchive a chat description: Archives or unarchives a chat. Archived chats are hidden from the main chat list. When archiving, the chat is automatically unpinned. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - archive properties: phone: type: string description: Phone number or group JID example: "5491155553333" archive: type: boolean description: True to archive, false to unarchive example: true last_message_timestamp: type: integer description: Unix timestamp of last message (optional) example: 1703123456 last_message_id: type: string description: ID of the last message (optional) example: "3EB0794DCEFA60" last_message_from_me: type: boolean description: Whether last message was sent by you (optional) example: false last_message_remote_jid: type: string description: Remote JID of last message (optional) example: "5491155553333@s.whatsapp.net" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Chat archived successfully", "jid": "5491155553333@s.whatsapp.net", "archived": true, }, "success": true, } /chat/mute: post: tags: - Chat summary: Mute or unmute a chat description: Mutes or unmutes notifications for a specific chat. Mute duration can be specified. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - mute properties: phone: type: string description: Phone number or group JID example: "5491155553333" mute: type: boolean description: True to mute, false to unmute example: true mute_duration: type: string description: Mute duration - "8h", "1w", or "always" (default is "always") example: "8h" enum: ["8h", "1w", "always"] responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Chat muted successfully", "jid": "5491155553333@s.whatsapp.net", "muted": true, "duration": "8h", }, "success": true, } /chat/star: post: tags: - Chat summary: Star or unstar a message description: Stars or unstars a specific message. Starred messages can be easily found later. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - chat_jid - message_id - star properties: chat_jid: type: string description: JID of the chat containing the message example: "5491155553333@s.whatsapp.net" sender_jid: type: string description: JID of message sender (optional, required for group messages) example: "5491155554444@s.whatsapp.net" message_id: type: string description: ID of the message to star/unstar example: "3EB0794DCEFA60" from_me: type: boolean description: Whether the message was sent by you example: false star: type: boolean description: True to star, false to unstar example: true responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Message starred successfully", "chat_jid": "5491155553333@s.whatsapp.net", "message_id": "3EB0794DCEFA60", "starred": true, }, "success": true, } /chat/delete-chat: post: tags: - Chat summary: Delete chat from chat list description: | Delete a chat entirely from the chat list. This is different from clearing chat history - it removes the chat from your chat list completely. **Important differences:** - **Delete Chat**: Removes chat from list (this endpoint) - **Clear Chat**: Only clears message history but keeps chat in list The chat will reappear in your list if you receive a new message from this contact. Optionally provide last message details for more precise deletion and better synchronization across devices. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone properties: phone: type: string description: Phone number or JID of the chat to delete example: "5521979232690" last_message_timestamp: type: integer format: int64 description: Unix timestamp of the last message (optional, improves sync) example: 1703123456 last_message_id: type: string description: ID of the last message (optional, improves sync) example: "3EB0794DCEFA60ABC123" last_message_from_me: type: boolean description: Whether the last message was sent by you (optional) example: false last_message_sender_jid: type: string description: JID of last message sender - required for group chats if providing message details (optional) example: "5521988887777@s.whatsapp.net" examples: simple: summary: "Simple delete (individual chat)" description: "Delete an individual chat without message details" value: phone: "5521979232690" complete_individual: summary: "Complete delete (individual chat with details)" description: "Delete individual chat with last message information for better sync" value: phone: "5521979232690" last_message_timestamp: 1703123456 last_message_id: "3EB0794DCEFA60ABC123" last_message_from_me: false complete_group: summary: "Complete delete (group chat)" description: "Delete group chat with last message details including sender" value: phone: "120363321748594524@g.us" last_message_timestamp: 1703123456 last_message_id: "3EB0794DCEFA60ABC123" last_message_from_me: false last_message_sender_jid: "5521988887777@s.whatsapp.net" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Chat deleted successfully", "jid": "5521979232690@s.whatsapp.net", }, "success": true, } 400: description: Bad Request content: application/json: schema: example: { "code": 400, "data": "missing phone in payload", "success": false, } 500: description: Internal Server Error content: application/json: schema: example: { "code": 500, "data": "failed to delete chat", "success": false, } /chat/list: get: tags: - Sync summary: List synchronized chats from local storage description: | Returns a list of chats that have already been synchronized to the local database. This endpoint queries the `whatsmeow_chat_settings` table directly. **Important Notes:** - Only returns chats that have been previously synchronized or modified - Does NOT include read/unread status (not stored locally) - Does NOT trigger new synchronization - Returns pinned, archived, and muted status **Use Cases:** - Display list of active chats - Show pinned/archived chats - Quick access to chat settings **For full synchronization:** Use `POST /sync/app-state` or `POST /sync/full-history` security: - ApiKeyAuth: [] responses: 200: description: Success content: application/json: schema: type: object properties: success: type: boolean example: true chats: type: array items: type: object properties: chat_jid: type: string description: Full JID of the chat example: "5521979232690@s.whatsapp.net" phone_number: type: string description: Extracted phone number from JID example: "5521979232690" muted_until: type: integer format: int64 description: Unix timestamp when mute expires (0 if not muted) example: 1735689600 pinned: type: boolean description: Whether chat is pinned example: true archived: type: boolean description: Whether chat is archived example: false stats: type: object properties: total: type: integer description: Total number of synchronized chats example: 45 pinned_count: type: integer description: Number of pinned chats example: 3 archived_count: type: integer description: Number of archived chats example: 12 muted_count: type: integer description: Number of muted chats example: 5 404: description: Client not found 500: description: Database query failed /sync/app-state: post: tags: - Sync summary: Force complete app state synchronization description: | Forces a complete synchronization of all 5 app state patch types without needing to reconnect to WhatsApp. This updates chat settings, blocks, and other WhatsApp configurations. **What this syncs:** - `critical_block`: Critical blocking data - `critical_unblock_low`: Critical unblocking (low priority) - `regular_low`: Regular patches (low priority) - `regular_high`: Regular patches (high priority) - `regular`: Standard patches **How it works:** 1. Calls `FetchAppState()` for each patch type 2. If `full_sync=true`, deletes local version to force complete resync 3. Updates local database automatically 4. No reconnection required **Auto Recovery Feature:** When `auto_recovery=true` (default), if a sync fails for any patch type, the system will automatically request a recovery from the primary device using `BuildAppStateRecoveryRequest()`. This requests an unencrypted snapshot of the app state from your phone, which helps recover from corrupted or incomplete sync data. **Use Cases:** - After device settings change - Periodic sync to ensure data consistency - Recover from sync issues (auto_recovery helps here) - Update chat settings (muted, pinned, archived) **Response Time:** Typically 2-5 seconds for all 5 patch types security: - ApiKeyAuth: [] requestBody: required: false content: application/json: schema: type: object properties: full_sync: type: boolean description: Whether to force full resync (deletes local version first) default: true example: true auto_recovery: type: boolean description: Whether to automatically request recovery from primary device if sync fails. Uses BuildAppStateRecoveryRequest to request unencrypted snapshot from phone. default: true example: true example: full_sync: true auto_recovery: true responses: 200: description: Sync completed (may contain partial errors) content: application/json: schema: type: object properties: success: type: boolean description: True if all patches synced successfully example: true message: type: string example: "App state synchronized successfully. All 5 patch types updated." results: type: array items: type: object properties: name: type: string description: Patch type name example: "critical_block" success: type: boolean description: Whether this patch synced successfully example: true error: type: string description: Error message if sync failed (omitted on success) example: "timeout waiting for patches" duration: type: string description: Time taken to sync this patch example: "1.234s" recovery_requested: type: boolean description: Whether recovery was requested for this patch (only present if auto_recovery enabled and sync failed) example: false auto_recovery_enabled: type: boolean description: Whether auto recovery was enabled for this sync request example: true example: success: true message: "App state synchronized successfully. All 5 patch types updated." auto_recovery_enabled: true results: - name: "critical_block" success: true duration: "1.234s" recovery_requested: false - name: "critical_unblock_low" success: true duration: "0.856s" recovery_requested: false - name: "regular_low" success: true duration: "0.523s" recovery_requested: false - name: "regular_high" success: true duration: "0.412s" recovery_requested: false - name: "regular" success: true duration: "0.678s" recovery_requested: false 400: description: Client not connected 404: description: Client not found /sync/history-request: post: tags: - Sync summary: Request history sync for specific chat (ON_DEMAND) description: | Sends an ON_DEMAND history sync request for a specific chat. The history arrives asynchronously via HistorySync events through your configured webhook or websocket. **How it works:** 1. You provide the oldest known message details 2. Request is sent to your primary device 3. Primary device sends history chunks asynchronously 4. History arrives via `HistorySync` events in webhook/websocket 5. Local database is updated automatically when events are processed **Requirements:** - Primary device must be online - Must have `oldest_message_id` from that chat - Message timestamp must be accurate **Use Cases:** - Load older messages for a specific chat - Recover missing messages - Pagination of chat history **Important:** - History does NOT arrive in HTTP response - Check webhook/websocket for `HistorySync` events - May take a few seconds to minutes depending on history size - Respects WhatsApp's rate limits security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - oldest_message_id - oldest_message_timestamp properties: phone: type: string description: Phone number or JID of the chat example: "5521979232690" oldest_message_id: type: string description: Message ID of the oldest message you have example: "3EB0ABCD1234567890" oldest_message_timestamp: type: integer format: int64 description: Unix timestamp in milliseconds of the oldest message example: 1704067200000 oldest_from_me: type: boolean description: Whether the oldest message was sent by you example: false count: type: integer format: int32 description: Number of messages to request (default 50, max depends on WhatsApp limits) default: 50 example: 100 examples: basic: summary: "Request 50 messages" value: phone: "5521979232690" oldest_message_id: "3EB0ABCD1234567890" oldest_message_timestamp: 1704067200000 oldest_from_me: false batch: summary: "Request 100 messages for pagination" value: phone: "5521979232690" oldest_message_id: "3EB0ABCD1234567890" oldest_message_timestamp: 1704067200000 oldest_from_me: true count: 100 responses: 200: description: Request sent successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "History sync request sent successfully. History will arrive asynchronously via HistorySync events (webhook/websocket)." request_id: type: string description: Request ID for tracking (same as oldest_message_id) example: "3EB0ABCD1234567890" chat: type: string description: Full JID of the chat example: "5521979232690@s.whatsapp.net" count: type: integer description: Number of messages requested example: 100 400: description: Invalid request (missing parameters or invalid JID) 404: description: Client not found 500: description: Failed to send request /sync/full-history: post: tags: - Sync summary: Request FULL history sync for ALL chats (FULL_HISTORY_SYNC_ON_DEMAND) description: | **REVOLUTIONARY FEATURE:** Requests a complete history synchronization for ALL chats, just like the initial connection sync. This is the first public implementation of WhatsApp's `FULL_HISTORY_SYNC_ON_DEMAND` protocol feature! **How it works:** 1. Configures sync period (days) and size limit (MB) 2. Sends `FULL_HISTORY_SYNC_ON_DEMAND` request to primary device 3. Primary device processes ALL chats within the specified period 4. History arrives asynchronously via multiple `HistorySync` events 5. Local database updates automatically as events are received 6. Works EXACTLY like initial WhatsApp connection sync **Configuration Options:** - **days_limit**: How far back to sync (7, 30, 90 days, etc.) - **size_mb_limit**: Maximum total size to prevent overload - **include_groups**: Whether to include group chat history - **include_calls**: Whether to include call history **Capabilities Enabled:** - Group history with full participant info - Bot/business message history - Reactions and polls - Message associations (replies, forwards) - Call logs (if enabled) - Guest chat history **Requirements:** - Primary device must be online - Primary device must have history available - Sufficient storage quota - No reconnection needed! **Use Cases:** - Periodic full backup of recent conversations - Recover all chats after data loss - Sync new secondary device - Get complete conversation history for reporting - Migrate chat data between systems **Performance:** - Request is immediate (< 1 second) - History arrives over minutes/hours depending on volume - Multiple `HistorySync` events will arrive - Watch webhook/websocket for events with matching `request_id` **Important Notes:** - History does NOT arrive in HTTP response - Monitor webhook/websocket for `HistorySync` events - Events contain `fullHistorySyncOnDemandRequestMetadata` with your `request_id` - Respects WhatsApp's quotas and limits - Primary device controls actual days/size based on availability security: - ApiKeyAuth: [] requestBody: required: false content: application/json: schema: type: object properties: days_limit: type: integer format: uint32 description: Number of days of history to sync (default 30) default: 30 example: 30 size_mb_limit: type: integer format: uint32 description: Maximum size in MB to download (default 1000 = 1GB) default: 1000 example: 1000 include_groups: type: boolean description: Include group chat history (default true) default: true example: true include_calls: type: boolean description: Include call log history (default false) default: false example: false examples: last_week: summary: "Sync last 7 days" description: "Quick sync of recent conversations" value: days_limit: 7 size_mb_limit: 500 include_groups: true include_calls: false last_month: summary: "Sync last 30 days (default)" description: "Standard monthly backup" value: days_limit: 30 size_mb_limit: 1000 include_groups: true include_calls: false last_quarter: summary: "Sync last 90 days" description: "Quarterly full backup" value: days_limit: 90 size_mb_limit: 2000 include_groups: true include_calls: true full_year: summary: "Sync last 365 days" description: "Complete annual history" value: days_limit: 365 size_mb_limit: 5000 include_groups: true include_calls: true responses: 200: description: Full history sync request sent successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Full history sync requested successfully. History will arrive asynchronously via HistorySync events (webhook/websocket). This works exactly like the initial connection sync." request_id: type: string description: Unique request ID for tracking (16-byte hex string) example: "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6" config: type: object description: Confirmed configuration used for the request properties: days_limit: type: integer example: 30 size_mb_limit: type: integer example: 1000 include_groups: type: boolean example: true include_calls: type: boolean example: false 400: description: Client not connected to WhatsApp 404: description: Client not found 500: description: Failed to send full history sync request /label/manage: post: tags: - Label summary: Create, edit or delete labels description: | Manages labels that can be applied to chats and messages for organization. **Label ID Format:** - Label IDs are **strings** in the format: `"label_" + unix_timestamp` - Example: `"label_1703123456"` (NOT a UUID or plain number) - When creating a new label, you can omit `label_id` and it will be auto-generated - When updating or deleting, you must provide the exact `label_id` string **Operations:** - **Create**: Omit `label_id` (auto-generated) or provide custom one, include `label_name` and `label_color` - **Update**: Provide `label_id`, `label_name`, and `label_color` - **Delete**: Provide `label_id` and set `delete: true` security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - label_name - label_color properties: label_id: type: string description: | Label ID in format "label_" + unix_timestamp (e.g., "label_1703123456"). - **Auto-generated if omitted** when creating new labels - **Required when deleting** (set delete: true) - **Optional when updating** existing labels example: "label_1703123456" label_name: type: string description: Name of the label (required for create/update, ignored for delete) example: "Important" label_color: type: integer description: Color code for the label (0-19, required for create/update, ignored for delete) example: 1 minimum: 0 maximum: 19 delete: type: boolean description: Set to true to delete the label (requires label_id) example: false default: false responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Label created successfully", "label_id": "label_1703123456", "label_name": "Important", "label_color": 1, }, "success": true, } /label/chat: post: tags: - Label summary: Apply or remove label from chat description: Applies or removes a label from a specific chat. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - label_id - apply properties: phone: type: string description: Phone number or group JID example: "5491155553333" label_id: type: string description: ID of the label to apply/remove example: "label_1703123456" apply: type: boolean description: True to apply label, false to remove example: true responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Label applied successfully", "jid": "5491155553333@s.whatsapp.net", "label_id": "label_1703123456", "applied": true, }, "success": true, } /label/message: post: tags: - Label summary: Apply or remove label from message description: Applies or removes a label from a specific message. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phone - message_id - label_id - apply properties: phone: type: string description: Phone number or group JID example: "5491155553333" message_id: type: string description: ID of the message example: "3EB0794DCEFA60" label_id: type: string description: ID of the label to apply/remove example: "label_1703123456" apply: type: boolean description: True to apply label, false to remove example: true responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "success": true, "message": "Label applied successfully", "jid": "5491155553333@s.whatsapp.net", "message_id": "3EB0794DCEFA60", "label_id": "label_1703123456", "applied": true, }, "success": true, } /group/create: post: tags: - Group summary: Create a new WhatsApp group description: Creates a new WhatsApp group with the specified name and participants. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CreateGroup" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "AnnounceVersionID": "1234567890", "DisappearingTimer": 0, "GroupCreated": "2023-12-01T10:00:00Z", "IsAnnounce": false, "IsEphemeral": false, "IsLocked": false, "JID": "120363123456789@g.us", "Name": "My New Group", "NameSetAt": "2023-12-01T10:00:00Z", "NameSetBy": "5491155554444@s.whatsapp.net", "OwnerJID": "5491155554444@s.whatsapp.net", "ParticipantVersionID": "1234567890", "Participants": [ { "IsAdmin": true, "IsSuperAdmin": true, "JID": "5491155554444@s.whatsapp.net", }, { "IsAdmin": false, "IsSuperAdmin": false, "JID": "5491155553333@s.whatsapp.net", }, ], }, "success": true, } /group/locked: post: tags: - Group summary: Set group locked status description: Configures whether only admins can modify group info (locked) or all participants can modify (unlocked). security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupLocked" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Group locked setting updated successfully", }, "success": true, } /group/ephemeral: post: tags: - Group summary: Set disappearing timer for group messages description: Configures ephemeral/disappearing messages for the group. Messages will automatically disappear after the specified duration. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupEphemeral" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Disappearing timer set successfully" }, "success": true, } /group/photo/remove: post: tags: - Group summary: Remove group photo description: Removes the current photo/image from the specified WhatsApp group. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/RemoveGroupPhoto" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Group photo removed successfully" }, "success": true, } /group/list: get: tags: - Group summary: List subscribed groups description: Returns complete list of subscribed groups. By default includes participant information. Use ignoreParticipants=true to exclude participants for better performance. security: - ApiKeyAuth: [] parameters: - in: query name: ignoreParticipants schema: type: boolean required: false description: Set to 'true' to exclude participants data from response for better performance (default is false) responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Groups": [ { "AnnounceVersionID": "1650572126123738", "DisappearingTimer": 0, "GroupCreated": "2022-04-21T17:15:26-03:00", "IsAnnounce": false, "IsEphemeral": false, "IsLocked": false, "JID": "120362023605733675@g.us", "Name": "Super Group", "NameSetAt": "2022-04-21T17:15:26-03:00", "NameSetBy": "5491155554444@s.whatsapp.net", "OwnerJID": "5491155554444@s.whatsapp.net", "ParticipantVersionID": "1650234126145738", "Participants": [ { "IsAdmin": true, "IsSuperAdmin": true, "JID": "5491155554444@s.whatsapp.net", }, { "IsAdmin": false, "IsSuperAdmin": false, "JID": "5491155553333@s.whatsapp.net", }, { "IsAdmin": false, "IsSuperAdmin": false, "JID": "5491155552222@s.whatsapp.net", }, ], "Topic": "", "TopicID": "", "TopicSetAt": "0001-01-01T00:00:00Z", "TopicSetBy": "", }, ], }, "success": true, } /group/invitelink: get: tags: - Group summary: Get Group Invite Link description: Gets the invite link for a group, optionally resetting it to create a new/different one security: - ApiKeyAuth: [] parameters: - in: query name: groupJID schema: type: string required: true description: The JID of the group to retrieve information from - in: query name: reset schema: type: boolean required: false description: Whether to revoke the old invite link and generate a new one (default is false) responses: 200: description: Successfull response content: application/json: schema: example: { "code": 200, "data": { "InviteLink": "https://chat.whatsapp.com/HffXhYmzzyJGec61oqMXiz", }, "success": true, } /group/info: get: tags: - Group summary: Gets group information description: Retrieves information about a specific group security: - ApiKeyAuth: [] parameters: - in: query name: groupJID schema: type: string required: true description: The JID of the group to retrieve information from responses: 200: description: Successful response content: application/json: schema: example: { "code": 200, "data": { "AnnounceVersionID": "1650572126123738", "DisappearingTimer": 0, "GroupCreated": "2022-04-21T17:15:26-03:00", "IsAnnounce": false, "IsEphemeral": false, "IsLocked": false, "JID": "120362023605733675@g.us", "Name": "Super Group", "NameSetAt": "2022-04-21T17:15:26-03:00", "NameSetBy": "5491155554444@s.whatsapp.net", "OwnerJID": "5491155554444@s.whatsapp.net", "ParticipantVersionID": "1650234126145738", "Participants": [ { "IsAdmin": true, "IsSuperAdmin": true, "JID": "5491155554444@s.whatsapp.net", }, { "IsAdmin": false, "IsSuperAdmin": false, "JID": "5491155553333@s.whatsapp.net", }, { "IsAdmin": false, "IsSuperAdmin": false, "JID": "5491155552222@s.whatsapp.net", }, ], "Topic": "", "TopicID": "", "TopicSetAt": "0001-01-01T00:00:00Z", "TopicSetBy": "", }, "success": true, } /group/photo: post: tags: - Group summary: Changes group photo description: Allows you to change a group photo/image. Returns the Picture ID number security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupPhoto" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Group Photo set successfully", "PictureID": "1222332123", }, "success": true, } /group/leave: post: tags: - Group summary: Leave a WhatsApp group description: Removes the authenticated user from the specified group. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupLeave" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Left group successfully" }, "success": true, } /group/name: post: tags: - Group summary: Change group name description: Updates the name of the specified WhatsApp group. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupName" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Group Name set successfully" }, "success": true, } /group/topic: post: tags: - Group summary: Set group topic/description description: Updates the topic or description of the specified WhatsApp group. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupTopic" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Group Topic set successfully" }, "success": true, } /group/announce: post: tags: - Group summary: Set group announce mode description: Enables or disables "announce" mode (admin-only messages) for the specified group. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupAnnounce" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Group Announce mode set successfully" }, "success": true, } /group/join: post: tags: - Group summary: Join a WhatsApp group via invite code description: Joins the WhatsApp group using the given invite code. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupJoin" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "Details": "Joined group successfully" }, "success": true, } /group/inviteinfo: post: tags: - Group summary: Get information about a group invite code description: Returns details about a WhatsApp group given an invite code. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupInviteInfo" responses: 200: description: Success content: application/json: schema: example: { "code": 200, "data": { "InviteInfo": { "GroupName": "Test Group", "GroupJID": "120363312246943103@g.us", }, }, "success": true, } /group/updateparticipants: post: tags: - Group summary: Add, Remove, Promote or Demote members in group description: Manage group members security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UpdateGroupParticipants" responses: 200: description: Response content: application/json: schema: example: { "code": 200, "data": { "Details": "Added to the group" }, "success": true, } /admin/global/stats: get: tags: - Admin Global summary: Get global system statistics description: | Returns comprehensive statistics for global webhook and RabbitMQ systems including: - Connection status and health - Active requests and performance metrics - Configuration details with masked sensitive data - System uptime and availability Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Global system statistics content: application/json: schema: example: { "enabled": true, "webhook": { "enabled": true, "url": "https://your-global-webhook.com/events", "events": ["All"], "timeout": "30s", "maxRetries": 3, "maxConcurrency": 50, "activeRequests": 5, "availableSlots": 45, }, "rabbitmq": { "enabled": true, "connected": true, "url": "amqp://user:***@rabbitmq:5672/", "exchange": "digigo.global", "queue": "digigo.events", "events": ["All"], }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } /admin/global/test: post: tags: - Admin Global summary: Test global systems connectivity description: | Tests connectivity and functionality of global webhook and RabbitMQ systems. This endpoint performs live connectivity tests and returns detailed results. Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Test results for global systems content: application/json: schema: example: { "webhook": { "enabled": true, "success": true, "error": null, "responseTime": "150ms", "httpStatus": 200, }, "rabbitmq": { "enabled": true, "success": true, "error": null, "connectionStatus": "connected", "exchangeExists": true, "queueExists": true, }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } /admin/global/config: get: tags: - Admin Global summary: Get global system configuration description: | Returns current global system configuration and available environment variables. Sensitive values like passwords and tokens are masked for security. Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Global system configuration content: application/json: schema: example: { "webhook": { "enabled": true, "url": "https://your-global-webhook.com/events", "events": ["All"], "timeout": "30s", "retryCount": 3, "maxConcurrency": 50, }, "rabbitmq": { "enabled": true, "url": "amqp://user:***@rabbitmq:5672/", "events": ["All"], "exchange": "digigo.global", "queue": "digigo.events", "exchange_type": "topic", "queue_type": "classic", "routing_key": "events.#", "durable": true, "auto_delete": false, "delivery_mode": 2, }, "environment_variables": { "GLOBAL_WEBHOOK_ENABLED": "Set to 'true' to enable global webhook", "GLOBAL_WEBHOOK_URL": "URL for global webhook endpoint", "GLOBAL_WEBHOOK_EVENTS": "Comma-separated list of events (or 'All')", "GLOBAL_RABBITMQ_ENABLED": "Set to 'true' to enable global RabbitMQ", "GLOBAL_RABBITMQ_URL": "RabbitMQ connection URL", "GLOBAL_RABBITMQ_EVENTS": "Comma-separated list of events (or 'All')", }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } /admin/global/config/reload: post: tags: - Admin Global summary: Reload global configuration description: | Reloads global webhook and RabbitMQ configurations from environment variables without restarting the service. This allows for dynamic configuration updates in production environments. Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Configuration reloaded successfully content: application/json: schema: example: { "success": true, "message": "Global configurations reloaded successfully", "stats": { "enabled": true, "webhook": { "enabled": true, "url": "https://your-global-webhook.com/events", "events": ["All"], }, "rabbitmq": { "enabled": true, "connected": true, "url": "amqp://user:***@rabbitmq:5672/", "exchange": "digigo.global", "queue": "digigo.events", }, }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } /admin/global/s3-retention/stats: get: tags: - Admin Global summary: Get S3 retention cleanup statistics operationId: getS3RetentionStats description: | Retrieves comprehensive statistics about the S3 retention cleanup system including: - Objects deleted and bytes reclaimed - Cycle count and last run information - Users processed and error counts - Current configuration settings The S3 retention system is a GLOBAL worker that periodically cleans expired objects from S3 storage based on each user's individual `s3_retention_days` configuration. Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: S3 retention statistics retrieved successfully content: application/json: schema: example: { "code": 200, "success": true, "data": { "enabled": true, "running": true, "currently_running": false, "last_run_time": "2025-01-15T10:30:00Z", "last_run_duration": "2m30s", "objects_deleted": 15420, "bytes_reclaimed": 1073741824, "error_count": 2, "users_processed": 45, "cycle_count": 24, "config": { "interval": "1h0m0s", "max_concurrency": 5, "batch_size": 1000, "objects_per_cycle": 10000, }, }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 503: description: S3 retention manager not initialized or not running content: application/json: schema: example: { "code": 503, "error": "S3 retention manager not initialized", "success": false, } /admin/global/s3-retention/trigger: post: tags: - Admin Global summary: Trigger S3 retention cleanup cycle operationId: triggerS3RetentionCycle description: | Manually triggers an S3 retention cleanup cycle. This is useful for: - Testing the cleanup process - Forcing immediate cleanup after configuration changes - Running cleanup outside the scheduled interval The cycle runs in the background. Use `/admin/global/s3-retention/stats` to monitor progress. Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Cleanup cycle triggered successfully content: application/json: schema: example: { "code": 200, "success": true, "message": "S3 retention cycle triggered. Check /admin/global/s3-retention/stats for progress.", } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 503: description: S3 retention manager not initialized or not running content: application/json: schema: example: { "code": 503, "error": "S3 retention manager is not running", "success": false, } /admin/global/event/test: post: tags: - Admin Global summary: Send test event through global systems description: | Sends a test event through the global webhook and RabbitMQ systems to verify end-to-end functionality. This is useful for testing integrations and troubleshooting event delivery. Requires admin token authentication. security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GlobalTestEvent" responses: 200: description: Test event dispatched successfully content: application/json: schema: example: { "success": true, "message": "Test event dispatched to global systems", "eventType": "AdminTest", "userID": "admin-test", "userToken": "admin-test", "data": { "test": true, "timestamp": 1705312845, "message": "This is a test event sent from the admin panel", }, } 400: description: Invalid request body content: application/json: schema: example: { "error": "invalid JSON" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } # Monitoring Endpoints /admin/events/stream: get: tags: - Admin Monitoring summary: Stream real-time monitoring events (SSE) description: | Streams live observability events as Server-Sent Events (SSE) for dashboards, incident tooling, and automation workflows. **Authentication** - Send Authorization: Bearer <admin_token> to receive the full firehose. - Or reuse a short-lived session token issued by POST /admin/events/session via the session query parameter. **Event Delivery** - Responses use the SSE framing (`id`, `event`, `data`) with text/event-stream content type. - The data field carries a JSON-encoded MonitoringEvent. - SSE clients should keep the TCP connection open and handle periodic heartbeats. **Filters** Combine query parameters to scope the stream by user, event type, status, or to replay backlog events using since_id / since_time. security: - AdminAuth: [] parameters: - name: session in: query description: Optional monitoring session token issued by POST /admin/events/session. When present, the Authorization header is not required. required: false schema: type: string example: "session_1720408476123456_abcd1234" - name: user_id in: query description: Filter events to a single user. Required when connecting with a non-admin session token. required: false schema: type: string example: "acct-01" - name: event_type in: query description: Filter by event type (e.g., message.sent, group.update) required: false schema: type: string example: "message.sent" - name: status in: query description: Filter by processing status (pending, processing, delivered, failed) required: false schema: type: string example: "failed" - name: since_id in: query description: Resume the stream after the specified event ID (useful for catch-up on reconnect). required: false schema: type: integer format: int64 example: 4500 - name: since_time in: query description: Only stream events created after this timestamp (RFC3339). required: false schema: type: string format: date-time example: "2024-05-12T15:04:05Z" - name: limit in: query description: Maximum number of cached events to send immediately on connect when since_id or since_time is provided (default 50, max 1000). required: false schema: type: integer minimum: 1 maximum: 1000 default: 50 example: 100 - name: only_failed in: query description: Set to true to only stream failed events (ignores other statuses unless explicitly set). required: false schema: type: boolean example: true responses: 200: description: Server-Sent Events stream containing monitoring events content: text/event-stream: schema: type: string description: Stream of SSE frames. Each data line contains a JSON encoded MonitoringEvent. example: | id: 4521 event: message.sent data: {"id":4521,"user_id":"acct-01","event_type":"message.sent","status":"delivered","attempts":1,"payload":{"raw":"{\"body\":\"Hello\"}"},"created_at":"2024-05-12T15:05:01Z","updated_at":"2024-05-12T15:05:04Z"} id: 4522 event: message.failed data: {"id":4522,"user_id":"acct-02","event_type":"message.failed","status":"failed","attempts":3,"payload":{"raw":"{\"body\":\"Hi\"}"},"created_at":"2024-05-12T15:05:15Z","updated_at":"2024-05-12T15:05:15Z"} 400: description: Invalid filter or malformed query parameters content: application/json: schema: example: { "error": 'Invalid filter: invalid limit: strconv.Atoi: parsing "abc": invalid syntax', } 401: description: Unauthorized - missing or invalid admin/session token content: application/json: schema: example: { "error": "Unauthorized" } 403: description: Forbidden - non-admin session must filter by user_id content: application/json: schema: example: { "error": "User token requires user_id filter" } 503: description: Monitoring system disabled content: application/json: schema: example: { "error": "Event monitoring is disabled" } /admin/events/history: get: tags: - Admin Monitoring summary: Query monitoring event history description: | Returns paginated monitoring events using the same filters available for the live stream. Useful for dashboards that need historical context or to backfill after downtime. Accepts the same authentication methods as the SSE stream (admin token or monitoring session token). security: - AdminAuth: [] parameters: - name: session in: query description: Optional monitoring session token issued by POST /admin/events/session. required: false schema: type: string example: "session_1720408476123456_abcd1234" - name: user_id in: query description: Filter events to a specific user. Required for non-admin session tokens. required: false schema: type: string example: "acct-01" - name: event_type in: query description: Filter by event type (e.g., message.sent, message.failed) required: false schema: type: string example: "message.failed" - name: status in: query description: Filter by processing status (pending, processing, delivered, failed) required: false schema: type: string example: "failed" - name: since_id in: query description: Return events with IDs greater than the provided value (forward pagination). required: false schema: type: integer format: int64 example: 4400 - name: since_time in: query description: Return events created after this timestamp (RFC3339). required: false schema: type: string format: date-time example: "2024-05-01T00:00:00Z" - name: limit in: query description: Maximum number of events to return per page (default 50, max 1000). required: false schema: type: integer minimum: 1 maximum: 1000 default: 50 example: 100 - name: only_failed in: query description: Set to true to only include failed events. required: false schema: type: boolean example: false responses: 200: description: Successfully retrieved monitoring events content: application/json: schema: type: object properties: events: type: array items: $ref: "#/definitions/MonitoringEvent" has_more: type: boolean description: Indicates if more events are available with the current filters. next_id: type: integer format: int64 description: Use as since_id to continue pagination. count: type: integer description: Number of events returned in this response. example: events: - id: 4521 user_id: "acct-01" event_type: "message.sent" status: "delivered" attempts: 1 payload: raw: '{"body":"Hello"}' created_at: "2024-05-12T15:05:01Z" updated_at: "2024-05-12T15:05:04Z" - id: 4522 user_id: "acct-02" event_type: "message.failed" status: "failed" attempts: 3 payload: raw: '{"body":"Hi"}' created_at: "2024-05-12T15:05:15Z" updated_at: "2024-05-12T15:05:15Z" has_more: false next_id: 0 count: 2 400: description: Invalid filter or malformed query parameters content: application/json: schema: example: { "error": 'Invalid filter: invalid since_id: strconv.ParseInt: parsing "abc": invalid syntax', } 401: description: Unauthorized - missing or invalid admin/session token content: application/json: schema: example: { "error": "Unauthorized" } 503: description: Monitoring system disabled content: application/json: schema: example: { "error": "Event monitoring is disabled" } /admin/events/stats: get: tags: - Admin Monitoring summary: Retrieve monitoring system statistics description: | Provides a snapshot of the monitoring subsystem including hub metrics, notifier status, aggregated event counts, and connected SSE clients. This endpoint always requires an admin token because it exposes system-wide state. security: - AdminAuth: [] responses: 200: description: Monitoring statistics retrieved successfully content: application/json: schema: $ref: "#/definitions/MonitoringStatistics" example: hub: connected_clients: 3 total_events_broadcast: 1284 total_events_delivered: 1279 cache_hits: 542 cache_misses: 38 cache_hit_rate: 0.9345 uptime_seconds: 86400 start_time: "2024-05-11T15:00:00Z" last_broadcast_at: "2024-05-12T15:07:32Z" notifier: enabled: true workers: 4 queue_size: 2 queue_capacity: 1000 queue_utilization: 0.002 events: by_status: delivered: 1200 failed: 54 pending: 30 by_type: message.sent: 890 message.failed: 54 message.received: 320 clients: - id: "client_1720454855123456_ab12cd34" session_token: "session_1720454855123456_abcd1234" user_id: "acct-01" is_admin: false connected: true connected_at: "2024-05-12T15:03:00Z" last_event_id: 4522 last_heartbeat: "2024-05-12T15:07:31Z" connection_time: 270.5 filter: user_id: "acct-01" event_type: "" status: "" since_id: 0 limit: 50 only_failed: false - id: "client_1720454700123456_ef56ab78" session_token: "session_1720454700123456_dcba4321" user_id: "" is_admin: true connected: true connected_at: "2024-05-12T15:00:00Z" last_event_id: 4522 last_heartbeat: "2024-05-12T15:07:30Z" connection_time: 450.1 filter: null 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "Unauthorized" } 503: description: Monitoring system disabled content: application/json: schema: example: { "error": "Event monitoring is disabled" } /admin/events/prune: post: tags: - Admin Monitoring summary: Manually prune persisted monitoring events description: | Deletes historic monitoring records older than the configured retention window. Useful for manual cleanup or before changing retention policies. When MONITORING_STORAGE_ENABLED is false the endpoint returns an error. security: - AdminAuth: [] requestBody: required: false content: application/json: schema: type: object properties: retention_hours: type: integer description: Optional cutoff in hours. Overrides the configured MONITORING_RETENTION_DAYS value for this request only. minimum: 1 additionalProperties: false example: retention_hours: 48 responses: 200: description: Prune executed successfully content: application/json: schema: type: object properties: deleted: type: integer description: Number of rows removed from monitoring_events. retention_h: type: number description: Retention window applied (hours). threshold: type: string format: date-time description: Events older than this timestamp were deleted. required: - deleted - retention_h - threshold example: deleted: 124 retention_h: 168 threshold: "2025-10-24T18:00:00Z" 400: description: Invalid request body (e.g. negative retention) content: application/json: schema: example: { "error": "Invalid body" } 401: description: Unauthorized - admin token required content: application/json: schema: example: { "error": "Unauthorized" } 503: description: Monitoring system disabled or persistence not enabled content: application/json: schema: example: { "error": "Event monitoring is disabled" } /admin/events/session: post: tags: - Admin Monitoring summary: Issue short-lived monitoring session token description: | Creates a temporary session token that can be used to authenticate SSE clients via the session query parameter. **Typical flow** 1. Admin dashboard calls this endpoint with an optional filter. 2. Use the returned session_token when connecting to /admin/events/stream. 3. Non-admin tokens are limited to the user_id included in the request filter. Accepts admin tokens or existing admin monitoring sessions for authentication. security: - AdminAuth: [] parameters: - name: session in: query description: Optional existing monitoring session token. Allows session renewal without re-supplying the admin token. required: false schema: type: string example: "session_1720408476123456_abcd1234" requestBody: required: false content: application/json: schema: $ref: "#/definitions/MonitoringSessionTokenRequest" example: filters: user_id: "acct-01" event_type: "message.failed" status: "" since_id: 0 limit: 50 only_failed: true responses: 200: description: Session token created successfully content: application/json: schema: $ref: "#/definitions/MonitoringSessionToken" example: session_token: "session_1720455000123456_90ab12cd" expires_at: "2024-05-12T15:10:00Z" stream_url: "/api/admin/events/stream?session=session_1720455000123456_90ab12cd&user_id=acct-01&event_type=message.failed" ttl_seconds: 300 400: description: Invalid request payload content: application/json: schema: example: { "error": 'Invalid filter: invalid limit: strconv.Atoi: parsing "-1": invalid syntax', } 401: description: Unauthorized - missing or invalid admin/session token content: application/json: schema: example: { "error": "Unauthorized" } 503: description: Monitoring system disabled content: application/json: schema: example: { "error": "Event monitoring is disabled" } # Dead Letter Queue (DLQ) Management Endpoints /admin/dlq: get: tags: - Admin DLQ summary: List Dead Letter Queue events description: | Retrieves all events stored in the Dead Letter Queue (DLQ) with advanced filtering capabilities. **Use Cases:** - Monitor failed events that exceeded MaxAttempts retry limit - Identify patterns in delivery failures across transports - Audit event processing issues for specific users or event types - Filter by time range to investigate incidents **Pagination:** - Default limit: 50 events (max: 1000) - Use offset for pagination through large result sets **Filters:** All filters are optional and can be combined for precise queries. Requires admin token authentication. security: - AdminAuth: [] parameters: - name: transport in: query description: Filter by transport name (e.g., "whatsapp", "rabbitmq", "webhook") required: false schema: type: string example: "whatsapp" - name: user_id in: query description: Filter by user ID who owns the failed event required: false schema: type: string example: "user123" - name: event_type in: query description: Filter by event type (e.g., "Message", "MessageUpdate", "Receipt") required: false schema: type: string example: "Message" - name: from_date in: query description: Filter events archived on or after this date (RFC3339 format) required: false schema: type: string format: date-time example: "2024-01-01T00:00:00Z" - name: to_date in: query description: Filter events archived on or before this date (RFC3339 format) required: false schema: type: string format: date-time example: "2024-01-31T23:59:59Z" - name: limit in: query description: Maximum number of events to return (default 50, max 1000) required: false schema: type: integer minimum: 1 maximum: 1000 default: 50 example: 100 - name: offset in: query description: Number of events to skip for pagination (default 0) required: false schema: type: integer minimum: 0 default: 0 example: 0 responses: 200: description: Successfully retrieved DLQ events content: application/json: schema: type: object properties: success: type: boolean example: true total: type: integer description: Total number of matching events example: 245 count: type: integer description: Number of events in current response example: 50 events: type: array items: $ref: "#/definitions/DLQEvent" example: success: true total: 245 count: 2 events: - id: 1234 transport: "whatsapp" user_id: "user123" event_type: "Message" payload: '{"body":"Hello","from":"5521971532700"}' attempts: 5 last_error: "network timeout after 30s" failed_at: "2024-01-15T10:30:00Z" archived_at: "2024-01-15T10:35:00Z" replay_count: 0 last_replay_at: null - id: 1235 transport: "rabbitmq" user_id: "user456" event_type: "MessageUpdate" payload: '{"status":"delivered"}' attempts: 3 last_error: "connection refused" failed_at: "2024-01-15T11:00:00Z" archived_at: "2024-01-15T11:05:00Z" replay_count: 1 last_replay_at: "2024-01-15T12:00:00Z" 400: description: Invalid query parameters content: application/json: schema: example: { "error": "invalid date format for from_date" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "database error" } delete: tags: - Admin DLQ summary: Bulk delete DLQ events with filters description: | Permanently deletes multiple events from the Dead Letter Queue based on filter criteria. **⚠️ WARNING: This operation is irreversible!** **Use Cases:** - Clean up old failed events after investigation - Remove events for deactivated users - Purge events for deprecated transports - Archive events after manual processing **Safety Features:** - Dry-run mode available to preview deletion (use dry_run=true) - Requires explicit confirmation (use confirm=true) - Returns count of events that will be/were deleted - Filters required to prevent accidental mass deletion **Best Practices:** 1. Always use dry_run=true first to preview 2. Verify the count matches expectations 3. Add specific filters to limit scope 4. Use confirm=true only after verification Requires admin token authentication. security: - AdminAuth: [] parameters: - name: transport in: query description: Filter by transport name required: false schema: type: string example: "whatsapp" - name: user_id in: query description: Filter by user ID required: false schema: type: string example: "user123" - name: event_type in: query description: Filter by event type required: false schema: type: string example: "Message" - name: from_date in: query description: Filter events archived on or after this date required: false schema: type: string format: date-time example: "2024-01-01T00:00:00Z" - name: to_date in: query description: Filter events archived on or before this date required: false schema: type: string format: date-time example: "2024-01-31T23:59:59Z" - name: dry_run in: query description: Preview deletion without executing (returns count) required: false schema: type: boolean default: false example: true - name: confirm in: query description: Explicit confirmation required for actual deletion required: false schema: type: boolean default: false example: true responses: 200: description: Deletion completed or dry-run preview content: application/json: schema: type: object properties: success: type: boolean deleted: type: integer description: Number of events deleted (or would be deleted in dry-run) dry_run: type: boolean description: Whether this was a dry-run message: type: string example: success: true deleted: 15 dry_run: false message: "Successfully deleted 15 DLQ events" 400: description: Invalid parameters or missing confirmation content: application/json: schema: example: { "error": "confirm=true required for actual deletion" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "database error" } /admin/dlq/stats: get: tags: - Admin DLQ summary: Get Dead Letter Queue statistics description: | Retrieves comprehensive statistics about the Dead Letter Queue for monitoring and analysis. **Provides:** - Total count of events in DLQ - Oldest and newest event timestamps - Breakdown by transport (whatsapp, rabbitmq, webhook, etc.) - Breakdown by event type (Message, Receipt, etc.) **Use Cases:** - Monitor DLQ growth trends - Identify problematic transports or event types - Plan cleanup or replay operations - Generate operational dashboards Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Successfully retrieved DLQ statistics content: application/json: schema: type: object properties: success: type: boolean example: true stats: $ref: "#/definitions/DLQStats" example: success: true stats: total_count: 1247 oldest_event: "2024-01-01T10:00:00Z" newest_event: "2024-01-15T14:30:00Z" by_transport: whatsapp: 856 rabbitmq: 234 webhook: 157 by_event_type: Message: 923 MessageUpdate: 187 Receipt: 98 Connected: 39 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "database error" } /admin/dlq/{id}: get: tags: - Admin DLQ summary: Get specific DLQ event details description: | Retrieves complete details for a single event in the Dead Letter Queue by its ID. **Includes:** - Full event metadata (transport, user, type, timestamps) - Complete payload (original event data) - Failure details (attempts, last error message) - Replay history (count, last replay time) **Use Cases:** - Investigate specific failed events - Verify payload data before replay - Analyze error messages for debugging - Audit event processing history Requires admin token authentication. security: - AdminAuth: [] parameters: - name: id in: path description: Unique DLQ event ID required: true schema: type: integer format: int64 example: 1234 responses: 200: description: Successfully retrieved DLQ event content: application/json: schema: type: object properties: success: type: boolean example: true event: $ref: "#/definitions/DLQEvent" example: success: true event: id: 1234 transport: "whatsapp" user_id: "user123" event_type: "Message" payload: '{"body":"Hello World","from":"5521971532700","to":"5491155553934@s.whatsapp.net","timestamp":1705312845}' attempts: 5 last_error: "network timeout after 30s - remote server unreachable" failed_at: "2024-01-15T10:30:00Z" archived_at: "2024-01-15T10:35:00Z" replay_count: 0 last_replay_at: null 404: description: DLQ event not found content: application/json: schema: example: { "error": "event not found in DLQ" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "database error" } delete: tags: - Admin DLQ summary: Delete specific DLQ event description: | Permanently deletes a single event from the Dead Letter Queue by its ID. **⚠️ WARNING: This operation is irreversible!** **Use Cases:** - Remove events after manual processing - Clean up obsolete or invalid events - Free up storage space - Remove sensitive data from DLQ **Best Practices:** 1. Retrieve event details first (GET /admin/dlq/{id}) 2. Verify it's the correct event to delete 3. Consider replay if event should be reprocessed 4. Document reason for deletion for audit trail Requires admin token authentication. security: - AdminAuth: [] parameters: - name: id in: path description: Unique DLQ event ID to delete required: true schema: type: integer format: int64 example: 1234 responses: 200: description: Successfully deleted DLQ event content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "DLQ event 1234 deleted successfully" 404: description: DLQ event not found content: application/json: schema: example: { "error": "event not found in DLQ" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "database error" } /admin/dlq/replay: post: tags: - Admin DLQ summary: Replay DLQ event back to buffer description: | Re-enqueues a failed event from the Dead Letter Queue back to the persistent buffer for retry. **Process:** 1. Retrieves event from DLQ by ID 2. Reconstructs original EventEnvelope from archived payload 3. Enqueues to persistent buffer with original transport 4. Updates replay statistics (replay_count, last_replay_at) 5. Optionally removes from DLQ after successful replay **Use Cases:** - Retry failed events after fixing underlying issues - Reprocess events after system recovery - Manually trigger event delivery - Test event processing pipeline **Safety Features:** - Dry-run mode available to preview replay - Original event data preserved - Replay history tracked - Automatic duplicate detection **Best Practices:** 1. Verify root cause is fixed before replay 2. Use dry_run=true to preview first 3. Monitor replay success in logs 4. Check event delivery confirmation Requires admin token authentication. security: - AdminAuth: [] requestBody: required: true content: application/json: schema: type: object required: - id properties: id: type: integer format: int64 description: DLQ event ID to replay example: 1234 dry_run: type: boolean description: Preview replay without executing default: false example: false remove_after: type: boolean description: Remove from DLQ after successful replay default: false example: true responses: 200: description: Replay completed or dry-run preview content: application/json: schema: type: object properties: success: type: boolean message: type: string event_id: type: integer description: ID of the replayed event transport: type: string description: Transport where event was replayed dry_run: type: boolean description: Whether this was a dry-run replay_count: type: integer description: Total number of times this event has been replayed example: success: true message: "Event 1234 replayed successfully to whatsapp transport" event_id: 1234 transport: "whatsapp" dry_run: false replay_count: 1 400: description: Invalid request body content: application/json: schema: example: { "error": "id is required" } 404: description: DLQ event not found content: application/json: schema: example: { "error": "event not found in DLQ" } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "error": "failed to replay event" } /admin/dlq/prune: post: tags: - Admin DLQ summary: Force event buffer prune description: | Triggers the event buffer pruning routine immediately, removing completed and DLQ items that exceed retention policies without waiting for the scheduled interval. Useful during maintenance windows or before deployments to ensure the buffer is clean. Requires admin authentication. security: - AdminAuth: [] responses: 200: description: Prune triggered successfully content: application/json: schema: example: { "success": true, "message": "prune triggered successfully", "pruner_stats": { "total_pruned": 1280, "total_archive_pruned": 430, "last_prune_time": "2025-10-15T02:10:21Z", "next_prune_time": "2025-10-15T03:10:21Z", }, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Failed to execute prune content: application/json: schema: example: { "success": false, "error": "failed to execute prune" } 501: description: Manual prune not supported for current buffer content: application/json: schema: example: { "success": false, "error": "manual prune not supported for current buffer", } /admin/archive: get: tags: - Admin Event Archive summary: List Event Archive description: | Retrieve all archived events including both DLQ (failed after max retries) and successfully delivered events. **Archive Types:** - **DLQ Events**: Events that failed after exceeding max retry attempts - **Success Events**: Events that were successfully delivered **Use Cases:** - Monitor complete event delivery history - Analyze success vs failure rates - Audit event processing for compliance - Investigate historical delivery patterns - Track replay history for events **Filtering:** - Filter by status (dlq, success, or all) - Filter by transport, user, event type - Date range filtering for temporal analysis - Combine filters for precise queries **Pagination:** - Default limit: 50 events (max: 1000) - Use offset for pagination through large result sets Requires admin token authentication. security: - AdminAuth: [] parameters: - name: status in: query description: Filter by archive status - 'dlq' for failed events, 'success' for successful events, or empty for all required: false schema: type: string enum: ["", "dlq", "success"] example: "success" - name: transport in: query description: Filter by transport name (webhook, rabbitmq, sqs, redis, websocket) required: false schema: type: string example: "webhook" - name: user_id in: query description: Filter by user ID who owns the archived event required: false schema: type: string example: "abc123" - name: event_type in: query description: Filter by event type (Message, MessageUpdate, Receipt, Connected, etc.) required: false schema: type: string example: "Message" - name: from_date in: query description: Filter events archived on or after this date (RFC3339 format) required: false schema: type: string format: date-time example: "2024-01-01T00:00:00Z" - name: to_date in: query description: Filter events archived on or before this date (RFC3339 format) required: false schema: type: string format: date-time example: "2024-12-31T23:59:59Z" - name: limit in: query description: Maximum number of events to return (default 50, max 1000) required: false schema: type: integer minimum: 1 maximum: 1000 default: 50 example: 50 - name: offset in: query description: Number of events to skip for pagination (default 0) required: false schema: type: integer minimum: 0 default: 0 example: 0 responses: 200: description: Successfully retrieved archive events content: application/json: schema: type: object properties: code: type: integer example: 200 data: type: array items: $ref: "#/definitions/ArchiveEvent" count: type: integer description: Number of events in current response example: 50 filter: $ref: "#/definitions/ArchiveFilter" success: type: boolean example: true example: code: 200 data: - id: 12345 status: "success" transport: "webhook" user_id: "abc123" event_type: "Message" payload: '{"body":"Hello World","from":"5521971532700"}' attempts: 1 last_error: null created_at: "2024-10-31T10:30:00Z" archived_at: "2024-10-31T15:45:00Z" replay_count: 0 last_replay_at: null - id: 12346 status: "dlq" transport: "rabbitmq" user_id: "xyz789" event_type: "MessageUpdate" payload: '{"status":"delivered"}' attempts: 5 last_error: "connection timeout" created_at: "2024-10-31T11:00:00Z" archived_at: "2024-10-31T14:30:00Z" replay_count: 1 last_replay_at: "2024-10-31T16:00:00Z" count: 2 filter: status: "" transport: "" user_id: "" event_type: "" limit: 50 offset: 0 success: true 400: description: Invalid query parameters content: application/json: schema: example: { "code": 400, "error": "invalid status filter", "success": false, "details": "status must be 'dlq', 'success', or empty for all", } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to retrieve archive events", "success": false, } delete: tags: - Admin Event Archive summary: Bulk delete Event Archive entries description: | Permanently remove multiple events from the archive based on filter criteria. **⚠️ WARNING: This operation is irreversible!** **Use Cases:** - Clean up old archived events after analysis - Remove events for deactivated users - Purge events for deprecated transports - Maintain archive size and performance **Safety Features:** - Requires at least one filter to prevent accidental mass deletion - Returns count of deleted and failed events - Supports bulk deletion with configurable limits **Best Practices:** 1. Always specify precise filters 2. Use reasonable limit values 3. Monitor deletion results 4. Verify filter matches expectations before deletion Requires admin token authentication. security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DeleteBulkRequest" example: status: "success" transport: "webhook" user_id: "abc123" limit: 100 responses: 200: description: Bulk deletion completed content: application/json: schema: type: object properties: code: type: integer example: 200 deleted: type: integer description: Number of events successfully deleted example: 95 failed: type: integer description: Number of events that failed to delete example: 5 total: type: integer description: Total number of events processed example: 100 filter: $ref: "#/definitions/ArchiveFilter" success: type: boolean example: true errors: type: array items: type: string description: Array of error messages for failed deletions (if any) example: code: 200 deleted: 95 failed: 5 total: 100 filter: status: "success" transport: "webhook" user_id: "abc123" limit: 100 success: true errors: - "Event ID 12350: database lock timeout" - "Event ID 12355: event not found" 400: description: Invalid request or missing required filters content: application/json: schema: example: { "code": 400, "error": "bulk deletion requires at least one filter (status, transport, user_id, or event_type)", "success": false, "details": "To delete all archive events, please use the admin interface with confirmation", } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to retrieve archive events", "success": false, } /admin/archive/stats: get: tags: - Admin Event Archive summary: Get Event Archive statistics description: | Retrieve comprehensive statistics about the Event Archive including total count, success/DLQ breakdown, oldest/newest events by status, and distributions by transport and event type. **Statistics Included:** - Total archive count (DLQ + Success) - Success vs DLQ breakdown - Oldest and newest events by status - Distribution by transport name - Distribution by event type - Distribution by status - Cross-tabulation by transport and status **Use Cases:** - Monitor system health and delivery rates - Track archive growth over time - Identify problematic transports or event types - Generate compliance and audit reports - Capacity planning for archive storage Requires admin token authentication. security: - AdminAuth: [] responses: 200: description: Successfully retrieved archive statistics content: application/json: schema: type: object properties: code: type: integer example: 200 data: $ref: "#/definitions/ArchiveStats" success: type: boolean example: true example: code: 200 data: total_count: 15234 success_count: 14890 dlq_count: 344 oldest_success: "2024-01-15T10:30:00Z" newest_success: "2024-10-31T15:45:00Z" oldest_dlq: "2024-01-16T08:20:00Z" newest_dlq: "2024-10-31T14:30:00Z" by_transport: webhook: 10000 rabbitmq: 5234 by_event_type: Message: 12000 Receipt: 3234 by_status: success: 14890 dlq: 344 by_transport_status: webhook: success: 9800 dlq: 200 rabbitmq: success: 5090 dlq: 144 success: true 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to retrieve archive statistics", "success": false, } /admin/archive/{id}: get: tags: - Admin Event Archive summary: Get specific Event Archive entry description: | Retrieve detailed information about a specific archived event (DLQ or Success) by ID. **Includes:** - Complete event payload - Archive status (dlq or success) - Delivery attempt history - Replay history - Timestamps (created, archived, last replay) - Error information (for DLQ events) **Use Cases:** - Investigate specific event delivery - Debug failed event details - Audit event processing history - Verify replay results - Extract event payload for reprocessing Requires admin token authentication. security: - AdminAuth: [] parameters: - name: id in: path required: true description: Archive event ID schema: type: integer format: int64 example: 12345 responses: 200: description: Successfully retrieved archive event content: application/json: schema: type: object properties: code: type: integer example: 200 data: $ref: "#/definitions/ArchiveEvent" success: type: boolean example: true example: code: 200 data: id: 12345 status: "success" transport: "webhook" user_id: "abc123" event_type: "Message" payload: '{"body":"Hello World","from":"5521971532700","to":"5491155553934@s.whatsapp.net","timestamp":1705312845}' attempts: 1 last_error: null created_at: "2024-10-31T10:30:00Z" archived_at: "2024-10-31T15:45:00Z" replay_count: 0 last_replay_at: null success: true 400: description: Invalid event ID content: application/json: schema: example: { "code": 400, "error": "invalid event ID", "success": false, "details": "event ID must be a valid number", } 404: description: Archive event not found content: application/json: schema: example: { "code": 404, "error": "archive event not found", "success": false, "details": "No archive event found with the specified ID", } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to retrieve archive event", "success": false, } delete: tags: - Admin Event Archive summary: Delete Event Archive entry description: | Permanently remove a specific event from the archive by ID. **⚠️ WARNING: This operation is irreversible!** **Use Cases:** - Remove specific problematic event - Clean up after manual investigation - Delete sensitive event data - Remove duplicate entries **Best Practices:** 1. Verify event ID before deletion 2. Export event data if needed for records 3. Use GET endpoint first to confirm event details Requires admin token authentication. security: - AdminAuth: [] parameters: - name: id in: path required: true description: Archive event ID to delete schema: type: integer format: int64 example: 12345 responses: 200: description: Event deleted successfully content: application/json: schema: type: object properties: code: type: integer example: 200 event_id: type: integer format: int64 example: 12345 message: type: string example: "Event deleted successfully" success: type: boolean example: true deleted: type: integer example: 1 400: description: Invalid event ID content: application/json: schema: example: { "code": 400, "error": "invalid event ID", "success": false, "details": "event ID must be a valid number", } 404: description: Archive event not found content: application/json: schema: example: { "code": 404, "error": "archive event not found", "success": false, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to delete archive event", "success": false, } /admin/archive/replay: post: tags: - Admin Event Archive summary: Replay Event Archive entries description: | Re-enqueue one or more archived events (DLQ or Success) back into the processing pipeline for retry. **Process:** 1. Retrieves event(s) from archive 2. Reconstructs original EventEnvelope from archived payload 3. Enqueues to persistent buffer with original transport 4. Updates replay statistics (replay_count, last_replay_at) 5. Event remains in archive for audit trail **Modes:** - **Single Replay**: Specify event_id to replay one event - **Bulk Replay**: Use filters to replay multiple events - **Dry Run**: Preview affected events without replaying **Use Cases:** - Retry failed events after fixing underlying issues - Reprocess successful events for testing - Re-deliver events after system recovery - Validate event processing pipeline **Safety Features:** - Dry-run mode available to preview replay - Original event data preserved in archive - Replay history tracked - Configurable bulk limits (max 1000) **Best Practices:** 1. Always use dry_run=true first to preview 2. Verify root cause is fixed before replay 3. Monitor replay success in logs 4. Check event delivery confirmation Requires admin token authentication. security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ReplayRequest" examples: single_replay: summary: Single event replay value: event_id: 12345 dry_run: false bulk_replay: summary: Bulk replay with filters value: status: "dlq" transport: "webhook" limit: 50 dry_run: false dry_run: summary: Dry run preview value: status: "success" user_id: "abc123" dry_run: true responses: 200: description: Replay completed or dry-run preview content: application/json: schema: type: object properties: code: type: integer example: 200 replayed: type: integer description: Number of events successfully replayed example: 45 failed: type: integer description: Number of events that failed to replay example: 5 total: type: integer description: Total number of events processed example: 50 dry_run: type: boolean description: Whether this was a dry-run example: false event_id: type: integer description: Event ID (for single replay) example: 12345 message: type: string example: "Event replayed successfully" filter: $ref: "#/definitions/ArchiveFilter" events: type: array items: $ref: "#/definitions/ArchiveEvent" description: Events that would be replayed (dry-run only) success: type: boolean example: true errors: type: array items: type: string description: Array of error messages for failed replays (if any) examples: single_success: summary: Single replay success value: code: 200 event_id: 12345 message: "Event replayed successfully" success: true replayed: 1 bulk_success: summary: Bulk replay success value: code: 200 replayed: 45 failed: 5 total: 50 filter: status: "dlq" transport: "webhook" limit: 50 success: true errors: - "Event ID 12350: buffer full" - "Event ID 12355: invalid payload" dry_run_preview: summary: Dry run preview value: code: 200 dry_run: true count: 10 filter: status: "success" user_id: "abc123" message: "Dry run - these events would be replayed" success: true replayed: 0 events: - id: 12345 status: "success" transport: "webhook" event_type: "Message" 400: description: Invalid request parameters content: application/json: schema: example: { "code": 400, "error": "invalid status filter", "success": false, "details": "status must be 'dlq', 'success', or empty for all", } 404: description: Archive event not found (single replay) content: application/json: schema: example: { "code": 404, "error": "archive event not found", "success": false, } 401: description: Unauthorized - Admin token required content: application/json: schema: example: { "error": "unauthorized - admin token required" } 500: description: Internal server error content: application/json: schema: example: { "code": 500, "error": "failed to replay archive event", "success": false, } /status/send/text: post: tags: - Status summary: Send a text status description: | Sends a text status to WhatsApp. Text status can include background colors and custom fonts. **Important Notes:** - Maximum text length: 650 characters - Background color and text color must be in ARGB format (decimal) - Use this ARGB generator: https://argb-int-calculator.netlify.app/ **Available Fonts:** - 0: SYSTEM - 1: SYSTEM_TEXT - 2: FB_SCRIPT - 6: SYSTEM_BOLD - 7: MORNINGBREEZE_REGULAR - 8: CALISTOGA_REGULAR - 9: EXO2_EXTRABOLD - 10: COURIERPRIME_BOLD security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/StatusText" responses: 200: description: Text status sent successfully content: application/json: schema: example: { "message_id": "3EB06F9067F80BAB89FF", "timestamp": "2024-01-15T10:30:00Z", "status": "sent", "type": "text_status", } /status/send/image: post: tags: - Status summary: Send an image status description: | Sends an image status to WhatsApp. Supports both base64 encoded data and HTTP(S) URLs. **Supported formats:** JPEG, PNG, GIF, WebP **Caption:** Optional text caption can be added security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/StatusImage" responses: 200: description: Image status sent successfully content: application/json: schema: example: { "message_id": "3EB06F9067F80BAB89FF", "timestamp": "2024-01-15T10:30:00Z", "status": "sent", "type": "image_status", } /status/send/video: post: tags: - Status summary: Send a video status description: | Sends a video status to WhatsApp. Supports both base64 encoded data and HTTP(S) URLs. **Supported formats:** MP4, 3GPP **Codec requirements:** H.264 video codec and AAC audio codec **Caption:** Optional text caption can be added security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/StatusVideo" responses: 200: description: Video status sent successfully content: application/json: schema: example: { "message_id": "3EB06F9067F80BAB89FF", "timestamp": "2024-01-15T10:30:00Z", "status": "sent", "type": "video_status", } /status/send/audio: post: tags: - Status summary: Send an audio status description: | Sends an audio status to WhatsApp. Supports both base64 encoded data and HTTP(S) URLs. **Supported formats:** OGG with Opus codec, MP3, M4A **PTT option:** Set `ptt: true` to send as voice note security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/StatusAudio" responses: 200: description: Audio status sent successfully content: application/json: schema: example: { "message_id": "3EB06F9067F80BAB89FF", "timestamp": "2024-01-15T10:30:00Z", "status": "sent", "type": "audio_status", "ptt": false, } /call/reject/send: post: tags: - Call summary: Reject a call and send custom message description: Rejects an incoming call with a specific rejection type and optionally sends a custom message to the caller security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CallRejectRequest" responses: 200: description: Call rejected successfully content: application/json: schema: type: object properties: success: type: boolean example: true call_id: type: string example: "call_12345_abcd" call_from: type: string example: "5521971532700@s.whatsapp.net" reject_type: type: string example: "busy" action: type: string example: "rejected" message_sent: type: boolean example: true example: success: true call_id: "call_12345_abcd" call_from: "5521971532700@s.whatsapp.net" reject_type: "busy" action: "rejected" message_sent: true 400: description: Bad request - Invalid input or missing required fields content: application/json: schema: type: object properties: error: type: string examples: missing_fields: value: error: "call_id and call_from are required" invalid_reject_type: value: error: "invalid reject_type, must be: busy, declined, or unavailable" invalid_jid: value: error: "invalid call_from JID: invalid format" 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string examples: client_not_initialized: value: error: "client not initialized" client_not_connected: value: error: "client not connected" call_reject_failed: value: error: "failed to reject call: network error" /community/link: post: tags: - Community summary: Link group to community description: Links a child group to a parent community. The authenticated user must be an admin of both the parent community and the child group to perform this operation. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/LinkGroupRequest" responses: 200: description: Group successfully linked to community content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Group linked to community successfully" parent_jid: type: string example: "120363025246487852@newsletter" child_jid: type: string example: "120363312246943103@g.us" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string example: "invalid parent JID format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "no session" /community/unlink: post: tags: - Community summary: Unlink group from community description: Unlinks a child group from a parent community. The authenticated user must be an admin of the parent community to perform this operation. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UnlinkGroupRequest" responses: 200: description: Group successfully unlinked from community content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Group unlinked from community successfully" parent_jid: type: string example: "120363025246487852@newsletter" child_jid: type: string example: "120363312246943103@g.us" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string example: "invalid parent JID format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error /community/linked-groups: post: tags: - Community summary: Get linked groups in community description: Retrieves all groups (sub-groups) linked to a parent community. Returns an array of group JIDs that are currently linked to the specified community. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/LinkedGroupsRequest" responses: 200: description: Linked groups retrieved successfully content: application/json: schema: $ref: "#/definitions/LinkedGroupsResponse" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string example: "invalid community JID format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error /community/sub-groups: post: tags: - Community summary: Get sub-groups in community description: Alias for /community/linked-groups. Retrieves all sub-groups linked to a parent community. Returns the same result as linked-groups endpoint. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/LinkedGroupsRequest" responses: 200: description: Sub-groups retrieved successfully content: application/json: schema: $ref: "#/definitions/LinkedGroupsResponse" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string example: "invalid community JID format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error /community/requests: post: tags: - Community summary: Get pending join requests description: Retrieves a list of participants who have requested to join the specified community group. Only available for communities/groups that require approval to join. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/GroupRequestsRequest" responses: 200: description: Join requests retrieved successfully content: application/json: schema: $ref: "#/definitions/GroupRequestsResponse" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string example: "invalid group JID format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error /community/requests/update: post: tags: - Community summary: Approve or reject join requests description: Approves or rejects pending join requests for a community group. The authenticated user must be an admin of the group to perform this operation. Supports bulk approval/rejection of multiple requests. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UpdateGroupRequestsRequest" responses: 200: description: Join requests processed successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Successfully approved 3 join request(s)" group_jid: type: string example: "120363312246943103@g.us" action: type: string enum: [approve, reject] example: "approve" processed_count: type: integer example: 3 participants: type: array items: type: string example: [ "5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net", ] 400: description: Bad request - Invalid JID format, missing required fields, or invalid action content: application/json: schema: type: object properties: error: type: string examples: invalid_group_jid: value: error: "invalid group JID format" invalid_action: value: error: "invalid action. Use 'approve' or 'reject'" missing_participants: value: error: "participants list is required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error /community/create: post: tags: - Community summary: Create new community description: Creates a new WhatsApp community with an initial set of linked groups. The community name is required, and you can optionally provide a list of existing group JIDs to link immediately upon creation. The authenticated user becomes the community admin. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CreateCommunityRequest" responses: 200: description: Community created successfully content: application/json: schema: $ref: "#/definitions/CreateCommunityResponse" 400: description: Bad request - Invalid input or missing required fields content: application/json: schema: type: object properties: error: type: string examples: missing_name: value: error: "community name is required" invalid_group_jid: value: error: "invalid group JID format in initial_groups" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to create community" /community/announcement: post: tags: - Community summary: Send community announcement description: Sends an announcement message to all members of a community. The message will be delivered to all linked groups within the community. Only community admins can send announcements. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/CommunityAnnouncementRequest" responses: 200: description: Announcement sent successfully content: application/json: schema: $ref: "#/definitions/CommunityAnnouncementResponse" 400: description: Bad request - Invalid JID format or missing required fields content: application/json: schema: type: object properties: error: type: string examples: missing_community_jid: value: error: "community JID is required" missing_message: value: error: "message text is required" invalid_jid: value: error: "invalid community JID format" 401: description: Unauthorized - Valid user token required 403: description: Forbidden - User is not a community admin content: application/json: schema: type: object properties: error: type: string example: "only community admins can send announcements" 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to send announcement" /business/resolve-link: post: tags: - Business summary: Resolve business message link description: Resolves a WhatsApp Business message link to retrieve detailed information about the business, including business name, category, description, website, email, address, and verification status. This is useful for validating business links before interacting with them. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ResolveBusinessLinkRequest" responses: 200: description: Business link resolved successfully content: application/json: schema: $ref: "#/definitions/BusinessLinkInfo" 400: description: Bad request - Invalid or missing business link content: application/json: schema: type: object properties: error: type: string example: "business link is required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to resolve business link" /business/contact-qr: post: tags: - Business summary: Get contact QR link description: Generates a QR code link for a WhatsApp contact. The QR code can be used to quickly add the contact or start a conversation. Optionally, you can revoke existing QR codes before generating a new one. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/ContactQRRequest" responses: 200: description: Contact QR link generated successfully content: application/json: schema: $ref: "#/definitions/ContactQRResponse" 400: description: Bad request - Invalid or missing phone number content: application/json: schema: type: object properties: error: type: string example: "phone number is required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to generate QR link" /business/bots: get: tags: - Business summary: Get available bots list description: Retrieves a list of all available WhatsApp Business bots that the authenticated user can interact with. Returns bot IDs, names, and basic information about each bot. security: - ApiKeyAuth: [] responses: 200: description: Bot list retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true bots: type: array items: $ref: "#/definitions/BotInfo" count: type: integer example: 5 description: Total number of available bots 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to retrieve bots list" /business/bot-profiles: post: tags: - Business summary: Get detailed bot profiles description: Retrieves detailed profile information for one or more WhatsApp Business bots. Returns comprehensive information including bot capabilities, commands, description, avatar, and configuration. Useful for displaying bot information in a user interface or for bot discovery. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/BotProfilesRequest" responses: 200: description: Bot profiles retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true profiles: type: array items: $ref: "#/definitions/BotProfileInfo" count: type: integer example: 2 description: Number of bot profiles returned 400: description: Bad request - Invalid or missing bot JIDs content: application/json: schema: type: object properties: error: type: string example: "bot JIDs are required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to retrieve bot profiles" /business/order/send: post: tags: - Business summary: Send order message to business description: Sends an order message to a WhatsApp Business account. The order message includes product details, quantities, prices, and can include multiple items. This is used for e-commerce and shopping interactions with business accounts. The business must support order messages. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SendOrderRequest" responses: 200: description: Order message sent successfully content: application/json: schema: $ref: "#/definitions/OrderResponse" 400: description: Bad request - Invalid input, missing required fields, or invalid order items content: application/json: schema: type: object properties: error: type: string examples: missing_phone: value: error: "phone number is required" missing_items: value: error: "order must contain at least one item" invalid_item: value: error: "invalid order item format" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to send order message" /device/users: post: tags: - Device summary: Get user devices description: Retrieves device information for one or more WhatsApp user JIDs. Returns details about all devices associated with each user, including device IDs and platform types (CHROME, SAFARI, DESKTOP, etc.). Useful for understanding which devices a user is using WhatsApp on. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UserDevicesRequest" responses: 200: description: User devices retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true devices: type: array items: $ref: "#/definitions/DeviceInfo" description: Array of device information for all requested users total_users: type: integer example: 2 description: Number of users queried total_devices: type: integer example: 4 description: Total number of devices found 400: description: Bad request - Invalid or missing user JIDs content: application/json: schema: type: object properties: error: type: string example: "user JIDs are required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to retrieve user devices" /device/users/context: post: tags: - Device summary: Get user devices with timeout context description: Retrieves device information for one or more WhatsApp user JIDs with a timeout context. This is similar to /device/users but includes timeout handling for better control over long-running requests. Returns details about all devices associated with each user. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UserDevicesRequest" responses: 200: description: User devices retrieved successfully with timeout context content: application/json: schema: type: object properties: success: type: boolean example: true devices: type: array items: $ref: "#/definitions/DeviceInfo" description: Array of device information for all requested users total_users: type: integer example: 2 description: Number of users queried total_devices: type: integer example: 4 description: Total number of devices found timeout_used: type: boolean example: false description: Whether the request timed out 400: description: Bad request - Invalid or missing user JIDs content: application/json: schema: type: object properties: error: type: string example: "user JIDs are required" 401: description: Unauthorized - Valid user token required 408: description: Request timeout - Operation took too long content: application/json: schema: type: object properties: error: type: string example: "request timeout while retrieving devices" 500: description: Internal server error /device/linked: get: tags: - Device summary: Get linked devices for current user description: Retrieves a list of all devices linked to the authenticated user's WhatsApp account. Returns information about each linked device including device ID, platform type, and connection status. This shows the multi-device configuration for the current session. security: - ApiKeyAuth: [] responses: 200: description: Linked devices retrieved successfully content: application/json: schema: $ref: "#/definitions/LinkedDevicesResponse" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string examples: no_session: value: error: "no session" not_connected: value: error: "client not connected" retrieval_failed: value: error: "failed to retrieve linked devices" /device/platform: post: tags: - Device summary: Get device platform name description: Retrieves the platform name (CHROME, SAFARI, FIREFOX, EDGE, DESKTOP, etc.) for a specific device based on its device ID. Useful for displaying device information in a user-friendly format or for device-specific logic. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DevicePlatformRequest" responses: 200: description: Device platform retrieved successfully content: application/json: schema: $ref: "#/definitions/DevicePlatformResponse" 400: description: Bad request - Invalid or missing device ID content: application/json: schema: type: object properties: error: type: string example: "device ID is required" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to retrieve device platform" /privacy/settings: get: tags: - Privacy summary: Get current privacy settings description: Retrieves all current privacy settings for the authenticated user including group_add, last_seen, status, profile, read_receipts, online, and call_add settings. Each setting shows who can see or interact with that feature (all, contacts, contact_blacklist, or none). security: - ApiKeyAuth: [] responses: 200: description: Privacy settings retrieved successfully content: application/json: schema: $ref: "#/definitions/PrivacySettingsResponse" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "no session" post: tags: - Privacy summary: Update a specific privacy setting description: Updates a specific privacy setting for the authenticated user. You can configure who can see your last seen, profile photo, status, who can add you to groups or calls, whether to send read receipts, and online status visibility. Each setting can be set to 'all' (everyone), 'contacts' (contacts only), 'contact_blacklist' (contacts except), or 'none' (nobody). security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/SetPrivacySettingRequest" responses: 200: description: Privacy setting updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Privacy setting last_seen updated to contacts" setting: type: string example: "last_seen" value: type: string example: "contacts" 400: description: Bad request - Invalid setting type or value content: application/json: schema: type: object properties: error: type: string examples: missing_fields: value: error: "missing setting or value in payload" invalid_setting: value: error: "invalid setting type" invalid_value: value: error: "invalid privacy value" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to update privacy setting" /privacy/disappearing-timer: post: tags: - Privacy summary: Set default disappearing message timer description: Sets the default disappearing message timer for new chats. Messages will automatically disappear after the specified duration. Valid options are 24h (24 hours), 7d (7 days), 90d (90 days), or 'off' to disable. This setting applies to new chats created after this configuration. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/DisappearingTimerRequest" responses: 200: description: Default disappearing timer set successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Default disappearing timer set to 24h" timer: type: string example: "24h" 400: description: Bad request - Invalid timer value content: application/json: schema: type: object properties: error: type: string examples: missing_timer: value: error: "missing timer in payload" invalid_timer: value: error: "invalid timer value. Use: 24h, 7d, 90d, or off" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to set disappearing timer" /privacy/blocklist: get: tags: - Privacy summary: Get blocklist of blocked contacts description: Retrieves the complete list of all contacts that have been blocked by the authenticated user. Returns an array of JIDs for all blocked contacts along with the total count. security: - ApiKeyAuth: [] responses: 200: description: Blocklist retrieved successfully content: application/json: schema: $ref: "#/definitions/BlocklistResponse" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to get blocklist" post: tags: - Privacy summary: Block or unblock contacts description: Blocks or unblocks one or more contacts. When blocking a contact, they will not be able to call you or send you messages. When unblocking, normal communication is restored. Supports bulk operations for multiple contacts at once. security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: "#/definitions/UpdateBlocklistRequest" responses: 200: description: Blocklist updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: "Successfully blocked 2 contact(s)" action: type: string enum: [block, unblock] example: "block" users: type: array items: type: string example: ["5491155553934", "5521971532700"] 400: description: Bad request - Invalid action or JID format content: application/json: schema: type: object properties: error: type: string examples: missing_fields: value: error: "missing action or users in payload" invalid_action: value: error: "invalid action. Use: block or unblock" invalid_jid: value: error: "invalid JID: 5491155553934" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "failed to update blocklist" /privacy/status: get: tags: - Privacy summary: Get status privacy setting description: Retrieves the current status privacy configuration for the authenticated user. This shows who can see your WhatsApp status updates. Possible values are 'all' (everyone), 'contacts' (contacts only), 'contact_blacklist' (contacts except specific ones), or 'none' (nobody). security: - ApiKeyAuth: [] responses: 200: description: Status privacy setting retrieved successfully content: application/json: schema: $ref: "#/definitions/StatusPrivacyResponse" 401: description: Unauthorized - Valid user token required 500: description: Internal server error content: application/json: schema: type: object properties: error: type: string example: "no session" definitions: ContextInfo: type: object description: "Optional context info for replies. When replying to a message, provide stanzaID, participant, and optionally quotedMessage for full reply preview support on all devices." properties: stanzaID: type: string example: "3EB06F9067F80BAB89FF" description: "Message ID to reply to (required for replies)" participant: type: string example: "5521971532700@s.whatsapp.net" description: "JID of original message sender (required for replies)" quotedMessage: $ref: "#/definitions/QuotedMessage" isForwarded: type: boolean example: true description: "Set to true to mark the message as forwarded. This is the preferred method for forwarding messages." mentionedJID: type: array items: type: string example: ["5521971532700@s.whatsapp.net", "5491155553934@s.whatsapp.net"] description: "Array of JIDs to mention in the message. Use full WhatsApp JID format (number@s.whatsapp.net)." mentionAll: type: boolean example: true description: "Set to true to mention all group members" QuotedMessage: type: object description: "The original message content being replied to. Providing this ensures proper reply preview display on all devices, especially iPhone. Without this field, replies will work but may not show the original message preview correctly on iOS devices." properties: conversation: type: string example: "Hello, how are you?" description: "The text content of the original message being replied to. Use this for simple text messages." example: conversation: "This is the original message text being replied to" DLQEvent: type: object description: "Represents an event stored in the Dead Letter Queue after exceeding MaxAttempts retry limit" properties: id: type: integer format: int64 description: "Unique identifier for the DLQ event" example: 1234 transport: type: string description: "Transport where the event failed (whatsapp, rabbitmq, webhook, etc.)" example: "whatsapp" user_id: type: string description: "ID of the user who owns this failed event" example: "user123" event_type: type: string description: "Type of the failed event (Message, MessageUpdate, Receipt, Connected, etc.)" example: "Message" payload: type: string description: "JSON string containing the complete original event data" example: '{"body":"Hello World","from":"5521971532700","to":"5491155553934@s.whatsapp.net","timestamp":1705312845}' attempts: type: integer description: "Number of delivery attempts made before archiving to DLQ" example: 5 last_error: type: string description: "Error message from the final failed delivery attempt" example: "network timeout after 30s - remote server unreachable" failed_at: type: string format: date-time description: "Timestamp when the event finally failed (RFC3339 format)" example: "2024-01-15T10:30:00Z" archived_at: type: string format: date-time description: "Timestamp when the event was archived to DLQ (RFC3339 format)" example: "2024-01-15T10:35:00Z" replay_count: type: integer description: "Number of times this event has been replayed from DLQ" example: 0 last_replay_at: type: string format: date-time nullable: true description: "Timestamp of the most recent replay attempt (null if never replayed)" example: null DLQStats: type: object description: "Statistical information about events in the Dead Letter Queue" properties: total_count: type: integer format: int64 description: "Total number of events currently in the DLQ" example: 1247 oldest_event: type: string format: date-time nullable: true description: "Timestamp of the oldest event in DLQ (null if DLQ is empty)" example: "2024-01-01T10:00:00Z" newest_event: type: string format: date-time nullable: true description: "Timestamp of the newest event in DLQ (null if DLQ is empty)" example: "2024-01-15T14:30:00Z" by_transport: type: object description: "Breakdown of event counts by transport name" additionalProperties: type: integer example: whatsapp: 856 rabbitmq: 234 webhook: 157 by_event_type: type: object description: "Breakdown of event counts by event type" additionalProperties: type: integer example: Message: 923 MessageUpdate: 187 Receipt: 98 Connected: 39 ArchiveEvent: type: object description: "Represents an archived event (DLQ or Successfully Delivered)" properties: id: type: integer format: int64 description: "Unique identifier for the archived event" example: 12345 status: type: string enum: ["dlq", "success"] description: "Archive status - 'dlq' for failed events after max retries, 'success' for successfully delivered events" example: "success" transport: type: string description: "Transport name where the event was processed (webhook, rabbitmq, sqs, redis, websocket)" example: "webhook" user_id: type: string description: "ID of the user who owns this archived event" example: "abc123" event_type: type: string description: "Type of the archived event (Message, MessageUpdate, Receipt, Connected, etc.)" example: "Message" payload: type: string description: "JSON string containing the complete original event data" example: '{"body":"Hello World","from":"5521971532700","to":"5491155553934@s.whatsapp.net","timestamp":1705312845}' attempts: type: integer description: "Number of delivery attempts made before archiving" example: 1 last_error: type: string nullable: true description: "Error message from the final failed delivery attempt (null for success status)" example: null created_at: type: string format: date-time description: "Timestamp when the event was originally created (RFC3339 format)" example: "2024-10-31T10:30:00Z" archived_at: type: string format: date-time description: "Timestamp when the event was archived (RFC3339 format)" example: "2024-10-31T15:45:00Z" replay_count: type: integer description: "Number of times this event has been replayed from archive" example: 0 last_replay_at: type: string format: date-time nullable: true description: "Timestamp of the most recent replay attempt (null if never replayed)" example: null ArchiveFilter: type: object description: "Filter parameters for querying archived events" properties: status: type: string enum: ["", "dlq", "success"] description: "Filter by status - 'dlq' for failed events, 'success' for successful events, empty for all" example: "success" transport: type: string description: "Filter by transport name" example: "webhook" user_id: type: string description: "Filter by user ID" example: "abc123" event_type: type: string description: "Filter by event type" example: "Message" from_date: type: string format: date-time description: "Filter events archived from this date onwards (RFC3339 format)" example: "2024-01-01T00:00:00Z" to_date: type: string format: date-time description: "Filter events archived up to this date (RFC3339 format)" example: "2024-12-31T23:59:59Z" limit: type: integer minimum: 1 maximum: 1000 default: 50 description: "Maximum number of events to return" example: 50 offset: type: integer minimum: 0 default: 0 description: "Number of events to skip for pagination" example: 0 ArchiveStats: type: object description: "Comprehensive statistics about the Event Archive" properties: total_count: type: integer format: int64 description: "Total number of archived events (DLQ + Success)" example: 15234 success_count: type: integer format: int64 description: "Number of successfully delivered archived events" example: 14890 dlq_count: type: integer format: int64 description: "Number of DLQ (failed) archived events" example: 344 oldest_success: type: string format: date-time nullable: true description: "Timestamp of the oldest success event (null if no success events)" example: "2024-01-15T10:30:00Z" newest_success: type: string format: date-time nullable: true description: "Timestamp of the newest success event (null if no success events)" example: "2024-10-31T15:45:00Z" oldest_dlq: type: string format: date-time nullable: true description: "Timestamp of the oldest DLQ event (null if no DLQ events)" example: "2024-01-16T08:20:00Z" newest_dlq: type: string format: date-time nullable: true description: "Timestamp of the newest DLQ event (null if no DLQ events)" example: "2024-10-31T14:30:00Z" by_transport: type: object description: "Breakdown of event counts by transport name" additionalProperties: type: integer example: webhook: 10000 rabbitmq: 5234 by_event_type: type: object description: "Breakdown of event counts by event type" additionalProperties: type: integer example: Message: 12000 Receipt: 3234 by_status: type: object description: "Breakdown of event counts by status" additionalProperties: type: integer example: success: 14890 dlq: 344 by_transport_status: type: object description: "Breakdown of event counts by transport and status" additionalProperties: type: object additionalProperties: type: integer example: webhook: success: 9800 dlq: 200 rabbitmq: success: 5090 dlq: 144 MonitoringEvent: type: object description: "Real-time monitoring event emitted by the observability pipeline" properties: id: type: integer format: int64 description: "Sequential identifier of the monitoring event" example: 4521 user_id: type: string description: "User associated with the event (empty for system-wide events)" example: "acct-01" event_type: type: string description: "Event topic emitted by the monitoring subsystem" example: "message.sent" payload: type: object description: "Structured payload captured for the event. Raw data is nested under the raw field when stored in SQL." additionalProperties: true example: raw: '{"body":"Hello"}' status: type: string description: "Processing status of the event" enum: [pending, processing, delivered, failed] example: "delivered" attempts: type: integer description: "Number of delivery attempts performed for this event" example: 1 created_at: type: string format: date-time description: "Timestamp when the event was created" example: "2024-05-12T15:05:01Z" updated_at: type: string format: date-time description: "Timestamp of the most recent update to the event" example: "2024-05-12T15:05:04Z" MonitoringEventFilter: type: object description: "Filter parameters available for monitoring streams and history queries" properties: user_id: type: string description: "Return events for a specific user ID" example: "acct-01" event_type: type: string description: "Return only events that match the provided event type" example: "message.failed" status: type: string description: "Filter events by processing status" enum: [pending, processing, delivered, failed] example: "failed" since_id: type: integer format: int64 description: "Return events with ID greater than this value" example: 4400 since_time: type: string format: date-time description: "Return events created after this timestamp (RFC3339)" example: "2024-05-01T00:00:00Z" limit: type: integer minimum: 1 maximum: 1000 default: 50 description: "Maximum number of events to return when querying history or issuing a session token" example: 50 only_failed: type: boolean description: "Restrict results to events whose status is failed" example: false MonitoringClientInfo: type: object description: "Metadata about a connected SSE monitoring client" properties: id: type: string description: "Unique identifier assigned to the SSE client connection" example: "client_1720454855123456_ab12cd34" session_token: type: string description: "Session token used by the client" example: "session_1720454855123456_abcd1234" user_id: type: string description: "User scope applied to the client (blank when connected as admin)" example: "acct-01" is_admin: type: boolean description: "Indicates whether the connection has admin privileges" example: false connected: type: boolean description: "Whether the client is actively connected" example: true connected_at: type: string format: date-time description: "Connection timestamp" example: "2024-05-12T15:03:00Z" last_event_id: type: integer format: int64 description: "Identifier of the last event delivered to the client" example: 4522 last_heartbeat: type: string format: date-time description: "Timestamp of the most recent heartbeat received from the client" example: "2024-05-12T15:07:31Z" connection_time: type: number format: float description: "Duration in seconds since the client connected" example: 270.5 filter: $ref: "#/definitions/MonitoringEventFilter" nullable: true description: "Filters currently applied to the client stream" MonitoringHubStats: type: object description: "Runtime metrics captured by the monitoring SSE hub" properties: connected_clients: type: integer description: "Number of clients currently connected to the hub" example: 3 total_events_broadcast: type: integer format: int64 description: "Total events broadcast to clients since startup" example: 1284 total_events_delivered: type: integer format: int64 description: "Total number of event deliveries performed" example: 1279 cache_hits: type: integer format: int64 description: "Number of cache hits when resolving queries" example: 542 cache_misses: type: integer format: int64 description: "Number of cache misses when resolving queries" example: 38 cache_hit_rate: type: number format: float description: "Ratio of cache hits versus total lookups (0.0 - 1.0)" example: 0.9345 uptime_seconds: type: integer format: int64 description: "Number of seconds the monitoring hub has been running" example: 86400 start_time: type: string format: date-time description: "Timestamp when the monitoring hub started" example: "2024-05-11T15:00:00Z" last_broadcast_at: type: string format: date-time nullable: true description: "Timestamp of the most recent broadcast" example: "2024-05-12T15:07:32Z" MonitoringNotifierStats: type: object description: "Operational metrics for the monitoring notifier workers" properties: enabled: type: boolean description: "Indicates if the notifier is currently dispatching events" example: true workers: type: integer description: "Number of concurrent notifier workers" example: 4 queue_size: type: integer description: "Current number of events waiting in the notifier queue" example: 2 queue_capacity: type: integer description: "Total capacity of the notifier queue" example: 1000 queue_utilization: type: number format: float description: "Queue utilization ratio (0.0 - 1.0)" example: 0.002 MonitoringStatistics: type: object description: "Aggregated telemetry exposed by the monitoring endpoints" properties: hub: $ref: "#/definitions/MonitoringHubStats" notifier: $ref: "#/definitions/MonitoringNotifierStats" events: type: object properties: by_status: type: object description: "Aggregated count of events by processing status" additionalProperties: type: integer example: delivered: 1200 failed: 54 by_type: type: object description: "Aggregated count of events by event type" additionalProperties: type: integer example: message.sent: 890 message.failed: 54 clients: type: array description: "Snapshot of currently connected SSE clients" items: $ref: "#/definitions/MonitoringClientInfo" MonitoringSessionTokenRequest: type: object description: "Payload for requesting a monitoring session token" properties: filters: $ref: "#/definitions/MonitoringEventFilter" description: "Optional filters to bake into the issued session token" MonitoringSessionToken: type: object description: "Response returned when issuing a monitoring session token" properties: session_token: type: string description: "Short-lived token to authenticate SSE connections" example: "session_1720455000123456_90ab12cd" expires_at: type: string format: date-time description: "Timestamp when the session token expires" example: "2024-05-12T15:10:00Z" stream_url: type: string description: "Pre-built stream URL including the session token and any requested filters" example: "/api/admin/events/stream?session=session_1720455000123456_90ab12cd&user_id=acct-01" ttl_seconds: type: integer description: "Time-to-live of the session token, in seconds" example: 300 ReplayRequest: type: object description: "Request parameters for replaying archived events" properties: event_id: type: integer format: int64 description: "Single event ID to replay (for single event replay)" example: 12345 dry_run: type: boolean default: false description: "Preview mode - returns events that would be replayed without actually replaying them" example: false status: type: string enum: ["", "dlq", "success"] description: "Filter by status for bulk replay" example: "dlq" transport: type: string description: "Filter by transport for bulk replay" example: "webhook" user_id: type: string description: "Filter by user ID for bulk replay" example: "abc123" event_type: type: string description: "Filter by event type for bulk replay" example: "Message" limit: type: integer minimum: 1 maximum: 1000 default: 50 description: "Maximum number of events to replay in bulk operation" example: 50 DeleteBulkRequest: type: object description: "Request parameters for bulk deletion of archived events" required: - status properties: status: type: string enum: ["dlq", "success"] description: "Filter by status for bulk deletion (required to prevent accidental delete all)" example: "dlq" transport: type: string description: "Filter by transport for bulk deletion" example: "webhook" user_id: type: string description: "Filter by user ID for bulk deletion" example: "abc123" event_type: type: string description: "Filter by event type for bulk deletion" example: "Message" limit: type: integer minimum: 1 maximum: 1000 default: 50 description: "Maximum number of events to delete in bulk operation" example: 50 User: type: object properties: id: type: string example: 4e4942c7dee1deef99ab8fd9f7350de5 name: type: string example: John Doe avatar_url: type: string example: "https://example.com/avatar.jpg" description: "URL of the user's WhatsApp profile avatar" token: type: string example: "1234ABCD" webhook: type: string example: "https://webhook.site/1234567890" jid: type: string example: "5491155551122:12@s.whatsapp.net" description: "WhatsApp JID (Jabber ID) of the connected account" qrcode: type: string example: "" description: "QR code data for pairing (empty when connected)" connected: type: boolean example: true description: "Whether the WhatsApp client is currently connected" loggedIn: type: boolean example: true description: "Whether the user is logged into WhatsApp" expiration: type: integer example: 0 description: "Account expiration timestamp (0 for no expiration)" events: type: string example: "All" skip_media_download: type: boolean example: false description: "Whether media download is skipped for this user" skip_groups: type: boolean example: false description: "Whether group messages are skipped for this user" skip_newsletters: type: boolean example: false description: "Whether newsletter messages are skipped for this user" skip_broadcasts: type: boolean example: false description: "Whether broadcast messages are skipped for this user" skip_own_messages: type: boolean example: false description: "Whether own messages are skipped for this user" echo_api_messages: type: boolean example: false description: "When true and global ECHO_API_MESSAGES_ENABLED is true, messages sent via API emit synthetic Message events flagged via Info.IsFromAPI." skip_calls: type: boolean example: false description: "Whether call events are skipped for this user" call_reject_message: type: string example: "Sorry, I cannot take calls at the moment." description: "Custom message sent when rejecting calls" call_reject_type: type: string example: "busy" description: "Type of call rejection (busy, decline or unavailable)" globalTransportSkips: $ref: "#/definitions/GlobalTransportSkipFlags" description: "Snapshot of the global dispatcher skip flags (webhook, RabbitMQ, SQS, Redis, WebSocket, S3)." isFromAPI: type: boolean example: false description: "Reflects the Echo API configuration. When true, API sends emit events with Info.IsFromAPI=true." proxy_config: type: object properties: enabled: type: boolean example: true proxy_url: type: string example: "https://serverproxy.com:9080" s3_config: type: object properties: enabled: type: boolean example: true endpoint: type: string example: "https://s3.amazonaws.com" region: type: string example: "us-east-1" bucket: type: string example: "my-bucket" access_key: type: string example: "***" path_style: type: boolean example: true public_url: type: string example: "https://s3.amazonaws.com" media_delivery: type: string example: "both" retention_days: type: integer example: 30 disable_acl: type: boolean example: true description: "Set to true for AWS S3 buckets with 'Bucket owner enforced' Object Ownership" rabbitmq_config: type: object properties: enabled: type: boolean example: true url: type: string example: "amqp://user:***@localhost:5672/" description: "RabbitMQ connection URL (password masked)" exchange: type: string example: "whatsapp.events" exchange_type: type: string example: "topic" queue: type: string example: "whatsapp.user.{user_id}" queue_type: type: string example: "classic" routing_key: type: string example: "whatsapp.{event_type}" events: type: string example: "Message,ReadReceipt,All" durable: type: boolean example: true auto_delete: type: boolean example: false exclusive: type: boolean example: false no_wait: type: boolean example: false delivery_mode: type: integer example: 2 dead_letter_exchange: type: string example: "dlx.whatsapp" dead_letter_routing_key: type: string example: "dlq.events" message_ttl: type: integer format: int64 example: 86400000 max_length: type: integer format: int64 example: 100000 max_length_bytes: type: integer format: int64 example: 104857600 queue_arguments: type: string example: '{"x-overflow":"reject-publish"}' exchange_arguments: type: string example: "{}" whatsapp_config: type: object properties: wa_version: type: string example: "2.3000.1026436087" description: "WhatsApp version string to emulate. This affects how the client identifies itself to WhatsApp servers." wa_platform: type: string example: "WEB" description: "WhatsApp platform being emulated" wa_release_channel: type: string example: "RELEASE" description: "WhatsApp release channel" wa_web_sub_platform: type: string example: "WEB_BROWSER" description: "WhatsApp web sub-platform" wa_os_name: type: string example: "Mac OS 10" description: "Operating system name" wa_os_version: type: string example: "10.15.7" description: "Operating system version" wa_device_name: type: string example: "Desktop" description: "Device name" wa_manufacturer: type: string example: "Apple" description: "Device manufacturer" wa_device_board: type: string example: "Mac-123456" description: "Device board identifier" wa_locale_language: type: string example: "en" description: "Locale language code" wa_locale_country: type: string example: "US" description: "Locale country code" wa_mcc: type: string example: "000" description: "Mobile Country Code" wa_mnc: type: string example: "000" description: "Mobile Network Code" wa_connect_type: type: string example: "WIFI_UNKNOWN" description: "Connection type" wa_platform_type: type: string example: "DESKTOP" description: "Platform type" CreateUser: type: object required: - name - token properties: name: type: string example: John Doe token: type: string example: "1234ABCD" webhook: type: string example: "https://webhook.site/1234567890" description: "Webhook URL to receive events" events: type: string example: "All" description: "Events to subscribe to. Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events). Ex: 'All', 'Message', 'Presence', 'Message,ReadReceipt,Connected'. Event names are case-sensitive; CSV values with spaces are normalized (for example: 'Message, Disconnected')." echoApiMessages: type: boolean example: false description: "Enable synthetic Message events for messages sent via API. Requires global ECHO_API_MESSAGES_ENABLED=true." skipMedia: type: boolean example: false description: "Skip processing messages from WhatsApp media. When enabled, only text messages will be processed, improving performance for applications that don't need media functionality. Default is false." skipGroups: type: boolean example: false description: "Skip processing messages from WhatsApp groups. When enabled, only direct messages will be processed, improving performance for applications that don't need group functionality. Default is false." skipNewsletters: type: boolean example: false description: "Skip processing messages from WhatsApp newsletters. When enabled, newsletter messages will be ignored, improving performance for applications that don't need newsletter functionality. Default is false." skipBroadcasts: type: boolean example: false description: "Skip processing messages from WhatsApp broadcasts and status updates. When enabled, broadcast messages and status updates will be ignored, improving performance for applications that don't need broadcast functionality. Default is false." skipOwnMessages: type: boolean example: false description: "Skip processing user's own messages. When enabled, messages sent by the user will be ignored, improving performance and avoiding message loops. Default is false." skipCalls: type: boolean example: false description: "Skip processing call events. When enabled, call offers, accepts, and terminations will be ignored, improving performance for applications that don't need call functionality. Default is false." callRejectMessage: type: string example: "Sorry, I cannot take calls at the moment." description: "Custom message to send when rejecting incoming calls. This message will be sent automatically when calls are rejected. Default is 'Sorry, I cannot take calls at the moment.'" callRejectType: type: string example: "busy" description: "Type of call rejection to use. Available options: 'busy' (indicates line is busy) or 'decline' (politely declines the call). Default is 'busy'." enum: ["busy", "decline", "unavailable"] globalTransportSkips: $ref: "#/definitions/GlobalTransportSkipsRequest" description: "Optional overrides for the global dispatcher skip flags (webhook, RabbitMQ, SQS, Redis, WebSocket, S3). Any flag omitted keeps the current value (defaults to false for new users)." proxyConfig: type: object properties: enabled: type: boolean example: true description: "Enable proxy for the user, default is false" proxyURL: type: string example: "https://serverproxy.com:9080" description: "Proxy URL to use for the user. Format: socks5://user:pass@host:port or http://host:port" s3Config: type: object description: "S3 storage configuration. Preferred keys are snake_case. camelCase aliases are also accepted for backward compatibility." properties: enabled: type: boolean example: true description: "Enable S3 for the user, default is false" endpoint: type: string example: "https://s3.amazonaws.com" region: type: string example: "us-east-1" bucket: type: string example: "my-bucket" access_key: type: string example: "1234567890" accessKey: type: string example: "1234567890" description: "camelCase alias for access_key" secret_key: type: string example: "1234567890" secretKey: type: string example: "1234567890" description: "camelCase alias for secret_key" path_style: type: boolean example: true description: "Enable path style for the user, default is false" pathStyle: type: boolean example: true description: "camelCase alias for path_style" public_url: type: string example: "https://s3.amazonaws.com" description: "Public URL for the user" publicUrl: type: string example: "https://s3.amazonaws.com" description: "camelCase alias for public_url" media_delivery: type: string example: "both" description: "Media delivery type for the user, default is both" mediaDelivery: type: string example: "both" description: "camelCase alias for media_delivery" retention_days: type: integer example: 30 retentionDays: type: integer example: 30 description: "camelCase alias for retention_days" disable_acl: type: boolean example: true description: "Set to true for AWS S3 buckets with 'Bucket owner enforced' Object Ownership" disableAcl: type: boolean example: true description: "camelCase alias for disable_acl" rabbitmqConfig: type: object properties: enabled: type: boolean example: true description: "Enable RabbitMQ for the user, default is false" url: type: string example: "amqp://guest:guest@localhost:5672/" description: "RabbitMQ connection URL" exchange: type: string example: "whatsapp.events" description: "Exchange name for events" exchange_type: type: string example: "topic" description: "Exchange type for events (required when enabled)" enum: ["topic", "direct", "fanout", "headers"] queue: type: string example: "whatsapp.user.{user_id}" description: "Queue name pattern" queue_type: type: string example: "classic" description: "Queue type for events (required when enabled)" enum: ["classic", "quorum", "stream"] routing_key: type: string example: "whatsapp.{event_type}" description: "Routing key pattern" events: type: string example: "All" description: "Event types to publish (comma-separated or 'All'). Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events). Event names are case-sensitive; CSV values with spaces are normalized (for example: 'Message, Disconnected')." durable: type: boolean example: true description: "Whether resources should be durable" auto_delete: type: boolean example: false description: "Whether resources should auto-delete" exclusive: type: boolean example: false description: "Whether queue should be exclusive" no_wait: type: boolean example: false description: "Whether to use no-wait mode" delivery_mode: type: integer example: 2 description: "Message delivery mode (1=non-persistent, 2=persistent)" dead_letter_exchange: type: string example: "dlx.whatsapp" description: "Dead Letter Exchange name. Rejected or expired messages will be routed to this exchange." dead_letter_routing_key: type: string example: "dlq.events" description: "Routing key for Dead Letter Exchange. Used when routing rejected/expired messages to DLQ." message_ttl: type: integer format: int64 example: 86400000 description: "Message TTL (Time To Live) in milliseconds. Messages older than this will be discarded or sent to DLX." max_length: type: integer format: int64 example: 100000 description: "Maximum number of messages in the queue. Overflow behavior depends on x-overflow setting." max_length_bytes: type: integer format: int64 example: 104857600 description: "Maximum total size of messages in the queue in bytes." queue_arguments: type: object additionalProperties: true example: { "x-overflow": "reject-publish" } description: "Custom queue arguments as JSON object. Supports any RabbitMQ queue argument like x-overflow, x-queue-master-locator, etc." exchange_arguments: type: object additionalProperties: true example: {} description: "Custom exchange arguments as JSON object. Supports any RabbitMQ exchange argument." connection_pool_size: type: integer example: 50 description: "Size of the connection pool for RabbitMQ connections. Higher values allow more concurrent operations." worker_count: type: integer example: 100 description: "Number of concurrent workers for message publishing." queue_buffer_size: type: integer example: 100000 description: "In-memory queue buffer size for event batching before publishing." batch_size: type: integer example: 1000 description: "Number of events to batch together before publishing." batch_timeout_ms: type: integer example: 100 description: "Maximum time in milliseconds to wait before publishing a partial batch." publish_timeout_ms: type: integer example: 5000 description: "Timeout in milliseconds for individual publish operations." max_retries: type: integer example: 3 description: "Maximum number of retry attempts for failed publish operations." retry_delay_ms: type: integer example: 1000 description: "Delay in milliseconds between retry attempts." whatsappConfig: type: object properties: waVersion: type: string example: "2.3000.1025473630" description: "WhatsApp version string to emulate. This affects how the client identifies itself to WhatsApp servers." waPlatform: type: string example: "WEB" description: "WhatsApp platform type to emulate." enum: ["WEB", "ANDROID", "IOS"] waReleaseChannel: type: string example: "RELEASE" description: "WhatsApp release channel to emulate." enum: ["RELEASE", "BETA"] waWebSubPlatform: type: string example: "WEB_BROWSER" description: "WhatsApp web sub-platform for web clients." enum: ["WEB_BROWSER", "DARWIN"] waOSName: type: string example: "Mac OS 10" description: "Operating system name to report to WhatsApp." waOSVersion: type: string example: "10.15.7" description: "Operating system version to report to WhatsApp." waDeviceName: type: string example: "Desktop" description: "Device name to report to WhatsApp." waManufacturer: type: string example: "Apple" description: "Device manufacturer to report to WhatsApp." waDeviceBoard: type: string example: "Mac-123456" description: "Device board identifier to report to WhatsApp." waLocaleLanguage: type: string example: "en" description: "Locale language code (ISO 639-1) for the WhatsApp client." waLocaleCountry: type: string example: "US" description: "Locale country code (ISO 3166-1 alpha-2) for the WhatsApp client." waMCC: type: string example: "000" description: "Mobile Country Code for network identification." waMNC: type: string example: "000" description: "Mobile Network Code for network identification." waConnectType: type: string example: "WIFI_UNKNOWN" description: "Connection type to report to WhatsApp." enum: ["WIFI_UNKNOWN", "CELLULAR_LTE", "CELLULAR_3G", "CELLULAR_2G"] waPlatformType: type: string example: "DESKTOP" description: "Platform type for client identification." enum: ["DESKTOP", "CHROME", "FIREFOX", "SAFARI", "EDGE"] GlobalTransportSkipsRequest: type: object description: "Partial update payload for per-transport skip flags. Omitted transports keep their existing state." additionalProperties: false properties: skipGlobalWebhook: type: boolean example: false description: "Skip sending events to the global webhook dispatcher." skipGlobalRabbitMQ: type: boolean example: false description: "Skip sending events to the global RabbitMQ dispatcher." skipGlobalSQS: type: boolean example: false description: "Skip sending events to the global SQS dispatcher." skipGlobalRedis: type: boolean example: false description: "Skip emitting events to the global Redis/pub-sub dispatcher." skipGlobalWebSocket: type: boolean example: false description: "Skip emitting events to the global WebSocket broadcaster." skipGlobalS3: type: boolean example: false description: "Skip the shared/global S3 enrichment pipeline." GlobalTransportSkipFlags: type: object properties: skipGlobalWebhook: type: boolean example: false skipGlobalRabbitMQ: type: boolean example: false skipGlobalSQS: type: boolean example: false skipGlobalRedis: type: boolean example: false skipGlobalWebSocket: type: boolean example: false skipGlobalS3: type: boolean example: false GlobalTransportSkipsState: allOf: - $ref: "#/definitions/GlobalTransportSkipFlags" - type: object properties: details: type: string example: "Global transport skip configuration retrieved successfully" GlobalTransportSkipsResponse: type: object properties: code: type: integer example: 200 data: $ref: "#/definitions/GlobalTransportSkipsState" success: type: boolean example: true EchoAPISettingsRequest: type: object required: - enabled properties: enabled: type: boolean example: true description: "Enable or disable API message echo. Requires global ECHO_API_MESSAGES_ENABLED=true." EchoAPISettingsResponse: type: object properties: EchoAPIMessages: type: boolean example: true description: "Indicates if synthetic Message events with Info.IsFromAPI are enabled." Details: type: string example: Echo API messages configuration updated successfully DeleteUser: type: object properties: id: type: string example: 4e4942c7dee1deef99ab8fd9f7350de5 GroupPhoto: type: object properties: GroupJID: type: string example: "120362023605733675@g.us" Image: type: string description: "Image data as base64 data URL (data:image/jpeg;base64,xxx) or HTTP(S) URL (https://example.com/image.jpg). Supported format: JPEG!" example: "data:image/jpeg;base64,Akd9300..." GroupInfo: type: object properties: GroupJID: type: string example: "120362023605733675@g.us" GroupInviteLink: type: object properties: GroupJID: type: string example: "120362023605733675@g.us" Reset: type: boolean example: false Connect: type: object properties: Subscribe: type: string example: ["Message", "ChatPresence", "Connected", "All"] description: "Array of event types to subscribe to. Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events)" Immediate: type: boolean DownloadImage: type: object required: - Url - MediaKey - Mimetype - FileSHA256 - FileLength properties: Url: type: string DirectPath: type: string MediaKey: type: string Mimetype: type: string FileEncSHA256: type: string FileSHA256: type: string FileLength: type: number ChatPresence: type: object required: - Phone - State properties: Phone: type: string example: "5521971532700" State: type: string example: composing Media: type: string example: audio UserPresence: type: object required: - type properties: type: type: string example: available MessageContact: type: object required: - Phone - Name - Vcard properties: Phone: type: string example: "5521971532700" description: "Phone number with country code" Name: type: string example: "John Doe" description: "Contact display name" Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID" Vcard: type: string example: "BEGIN:VCARD\nVERSION:3.0\nN:Doe;John;;;\nFN:John Doe\nORG:Example.com Inc.;\nTITLE:Imaginary test person\nEMAIL;type=INTERNET;type=WORK;type=pref:johnDoe@example.org\nTEL;type=WORK;type=pref:+1 617 555 1212\nTEL;type=WORK:+1 (617) 555-1234\nTEL;type=CELL:+1 781 555 1212\nTEL;type=HOME:+1 202 555 1212\nitem1.ADR;type=WORK:;;2 Enterprise Avenue;Worktown;NY;01111;USA\nitem1.X-ABADR:us\nitem2.ADR;type=HOME;type=pref:;;3 Acacia Avenue;Hoitem2.X-ABADR:us\nEND:VCARD" description: "Contact information in vCard format" NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator" Duration: type: integer example: 86400 description: "Message expiration time in seconds" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageLocation: type: object required: - Phone - Latitude - Longitude properties: Phone: type: string example: "5521971532700" description: "Phone number with country code" Name: type: string example: "Eiffel Tower" description: "Optional location name or description" Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID" Latitude: type: number format: float example: 48.858370 description: "Location latitude coordinate" Longitude: type: number format: float example: 2.294481 description: "Location longitude coordinate" NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator" Duration: type: integer example: 86400 description: "Message expiration time in seconds" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" ReactionText: type: object required: - Phone - Body - Id properties: Phone: type: string example: "5521971532700" Body: type: string example: "❤️" Id: type: string example: "me:3EB06F9067F80BAB89FF" MessagePoll: type: object required: - Group - Header - Options properties: Group: type: string example: "120363417042313103@g.us" description: "Group JID where to send the poll" Header: type: string example: "What's your favorite color?" description: "Poll question/header text" Options: type: array description: "Array of poll options (minimum 2, maximum 12)" items: type: string example: "Red" minItems: 2 maxItems: 12 MaxAnswer: type: integer example: 1 description: "Maximum number of answers per user. If not set to 1, all options will be available for selection (accepts both 'max_answer' and 'MaxAnswer' for compatibility)" Id: type: string example: "3EB06F9067F80BAB89FF" description: "Optional custom message ID" NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator (accepts both 'presence' and 'Presence' for compatibility)" Duration: type: integer example: 86400 description: "Message expiration time in seconds (accepts both 'duration' and 'Duration' for compatibility)" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageList: type: object required: - Phone - Text - ButtonText - Sections properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Id: type: string example: "LIST_001" description: "Optional custom message ID. If not provided, a random one will be generated." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator (accepts both 'presence' and 'Presence' for compatibility)" Text: type: string example: "Choose one of the options below" description: "Main list description text. Maximum 1024 characters. This explains what the list is about." Title: type: string example: "Product Catalog" description: "Optional list title/header. Maximum 60 characters. Displayed at the top of the list." Footer: type: string example: "Powered by DigiGO API" description: "Optional footer text. Maximum 60 characters. Displayed at the bottom of the list." ButtonText: type: string example: "View Options" description: "Text for the main action button that opens the list. Maximum 20 characters." Sections: type: array description: "Array of list sections. Maximum 10 sections allowed." maxItems: 10 items: type: object required: - Title - Rows properties: Title: type: string example: "Main Products" description: "Section title. Maximum 24 characters." Rows: type: array description: "Array of rows in this section. Maximum 10 rows per section." maxItems: 10 items: type: object required: - RowId - Title - Description properties: RowId: type: string example: "product_1" description: "Unique identifier for this row. Used in response callbacks." Title: type: string example: "Premium Package" description: "Row title/name. Maximum 24 characters." Description: type: string example: "Complete package with all features included" description: "Row description. Maximum 72 characters." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageText: type: object required: - Phone - Body properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Body: type: string example: "How you doin" description: "Text message content. Supports Unicode, emojis, and formatting. Maximum 4096 characters." Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID. If not provided, a random one will be generated." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator before sending message. Useful for natural conversation flow." Duration: type: integer example: 86400 description: "Message expiration time in seconds. Valid values: 86400 (24h), 604800 (7 days), 7776000 (90 days)." LinkPreview: type: boolean example: true description: "Set to true to enable automatic link preview for URLs in the message text." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" example: Phone: "5521971532700" Body: "This is my reply to your message" Id: "ABCDABCD1234" Presence: 3000 Duration: 86400 LinkPreview: true NumberCheck: true EchoApi: false ContextInfo: stanzaID: "3EB06F9067F80BAB89FF" participant: "5511888888888@s.whatsapp.net" quotedMessage: conversation: "Original message text being replied to" isForwarded: false mentionedJID: - "5521971532700@s.whatsapp.net" mentionAll: false MessageLink: type: object required: - Phone - Link properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Link: type: string example: "https://example.com" description: "Link to send. Must be a valid URL." Caption: type: string example: "Link Description" description: "Optional caption for the link. Maximum 1024 characters. Supports Unicode and emojis." Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID. If not provided, a random one will be generated." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageImage: type: object required: - Phone - Image properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Image: type: string example: "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==" description: "Image data as base64 data URL (data:image/jpeg;base64,xxx) or HTTP(S) URL (https://example.com/image.jpg). Supported formats: JPEG, PNG, GIF, WebP. Maximum size: 5MB." Caption: type: string example: "Image Description" description: "Optional caption for the image. Maximum 1024 characters. Supports Unicode and emojis." Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID. If not provided, a random one will be generated." MimeType: type: string example: "image/jpeg" description: "Optional MIME type override. Supported: image/jpeg, image/png, image/gif, image/webp. Auto-detected if not provided." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator before sending message." ViewOnce: type: boolean example: true description: "Set to true for disappearing message after viewing (view once). Cannot be combined with Duration." Duration: type: integer example: 86400 description: "Message expiration time in seconds. Valid values: 86400 (24h), 604800 (7 days), 7776000 (90 days)." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageAudio: type: object required: - Phone - Audio properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Audio: type: string example: "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABK" description: "Audio data as base64 data URL (data:audio/ogg;base64,xxx) or HTTP(S) URL (https://example.com/audio.ogg). Supported formats: OGG, MP3, AAC, M4A, WAV. Maximum size: 16MB." Caption: type: string example: "Voice message caption" description: "Optional caption for the audio. Maximum 1024 characters. Supports Unicode and emojis." Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID. If not provided, a random one will be generated." PTT: type: boolean example: true description: "Set to true for voice note (push-to-talk), false for audio file. Voice notes show with different UI and waveform. Default: true." Presence: type: integer example: 3000 description: "Milliseconds to simulate recording indicator before sending message. Useful for natural conversation flow." ViewOnce: type: boolean example: true description: "Set to true for disappearing message after viewing (view once). Cannot be combined with Duration." Duration: type: integer example: 86400 description: "Message expiration time in seconds. Valid values: 86400 (24h), 604800 (7 days), 7776000 (90 days)." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageVideo: type: object required: - Phone - Video properties: Phone: type: string example: "5521971532700" description: "Phone number with country code (accepts both 'phone' and 'Phone' for compatibility)" Video: type: string example: "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE=" description: "Video data as base64 data URL (data:video/mp4;base64,xxx) or HTTP(S) URL (https://example.com/video.mp4) (accepts both 'video' and 'Video' for compatibility)" Caption: type: string example: "my video" description: "Optional caption for the video (accepts both 'caption' and 'Caption' for compatibility)" Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID (accepts both 'id' and 'Id' for compatibility)" MimeType: type: string example: "video/mp4" description: "Optional MIME type override (video/mp4, video/3gpp, video/quicktime, video/x-ms-asf) (accepts both 'mimetype' and 'MimeType' for compatibility)" JPEGThumbnail: type: string format: byte description: "Optional JPEG thumbnail as base64 string (accepts both 'jpegthumbnail' and 'JPEGThumbnail' for compatibility)" example: "/9j/4AAQSkZJRgABAQEAYABgAAD/..." Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator" ViewOnce: type: boolean example: true description: "Set to true for disappearing message after viewing (accepts both 'view_once' and 'ViewOnce' for compatibility)" Duration: type: integer example: 86400 description: "Message expiration time in seconds (accepts both 'duration' and 'Duration' for compatibility)" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessagePTV: type: object required: - Phone - Video properties: Phone: type: string example: "5521971532700" description: "Phone number with country code (accepts both 'phone' and 'Phone' for compatibility)" Video: type: string example: "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE=" description: "Video data as base64 data URL (data:video/mp4;base64,xxx) or HTTP(S) URL (https://example.com/video.mp4) for PTV message (accepts both 'video' and 'Video' for compatibility)" MessageEvent: type: object required: - Phone - Name - StartTime properties: Phone: type: string example: "5521971532700" description: "Phone number with country code. Must include country code without + symbol (e.g., 5521971532700)." Name: type: string example: "Team Meeting" description: "Event title/name. Maximum 255 characters." Description: type: string example: "Weekly team sync meeting to discuss project updates" description: "Optional detailed event description. Maximum 1024 characters. Supports Unicode and emojis." StartTime: type: integer format: int64 example: 2524608000 description: "Event start time as Unix timestamp (seconds since epoch). Required field." EndTime: type: integer format: int64 example: 2556143999 description: "Event end time as Unix timestamp (seconds since epoch). Optional, but recommended." ExtraGuestsAllowed: type: boolean example: true description: "Set to true to allow participants to invite additional guests to the event." IsCanceled: type: boolean example: false description: "Set to true to mark the event as cancelled. Default: false." IsScheduleCall: type: boolean example: true description: "Set to true if this is a scheduled call event (video/voice meeting)." Id: type: string example: "EVENT_001" description: "Optional custom message ID. If not provided, a random one will be generated." Presence: type: integer example: 2000 description: "Milliseconds to simulate typing indicator before sending event." NumberCheck: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." Location: type: object description: "Optional event location details with GPS coordinates." properties: Name: type: string example: "Conference Room A, Main Office" description: "Location name or address. Maximum 255 characters." DegreesLatitude: type: number format: float example: -23.5505 description: "Latitude coordinate for the location (GPS)." DegreesLongitude: type: number format: float example: -46.6333 description: "Longitude coordinate for the location (GPS)." EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" ButtonsMessage: type: object description: "Interactive message with buttons." required: - phone - buttons properties: phone: type: string example: "5521971532700" description: "Recipient phone number with country code (without +) or group JID (e.g., 120363312246943103@g.us)." title: type: string example: "Pagamento PIX" description: "Optional heading displayed above the body. Recommended maximum of 60 characters." body: type: string example: "Escaneie o QR Code para pagar via PIX" description: "Primary message text. Use this or text when not sending media headers." text: type: string example: "Escolha uma opção abaixo" description: "Alternative field for the primary text. When media headers are present, prefer caption/text over body." footer: type: string example: "Equipe DigiGO" description: "Optional footer text displayed below the buttons." caption: type: string example: "Oferta da semana" description: "Optional media caption when using image/video/document headers." image: type: object description: "Optional image header." required: - url properties: url: type: string format: uri example: "https://picsum.photos/600/400.jpg" description: "HTTP(S) or data URL pointing to the image." video: type: object description: "Optional video header." required: - url properties: url: type: string format: uri example: "https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4" description: "HTTP(S) or data URL pointing to the video file." document: type: object description: "Optional document header (PDF, DOC, etc.)." required: - url properties: url: type: string format: uri example: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" description: "HTTP(S) or data URL pointing to the document." buttons: type: array description: "Array of interactive buttons." minItems: 1 maxItems: 10 items: type: object required: - buttonId - buttonText - type properties: buttonId: type: string example: "pix_btn_1" description: "Unique button identifier returned in callbacks." buttonText: type: object description: "Label configuration for the button." required: - displayText properties: displayText: type: string example: "Pagar com PIX" description: "Button label shown to end users." type: type: string enum: [ quick_reply, reply, url, cta_url, call, cta_call, copy, cta_copy, pix, pix_payment, payment_info, review_and_pay, ] example: "pix" description: "Button action type. Use `pix`/`payment_info` for PIX payments, `review_and_pay` for order payments, and quick_reply/cta_* for interactive actions." url: type: string format: uri example: "https://exemplo.com/oferta" description: "Destination URL for url/cta_url buttons." merchant_url: type: string format: uri example: "https://store.example.com/checkout" description: "Alternative merchant URL for url buttons." phone: type: string example: "+5511988888888" description: "Phone number in E.164 format for call/cta_call buttons." code: type: string example: "CUPOM123" description: "Coupon or code copied when using copy/cta_copy buttons." pix_key: type: string example: "11999999999" description: "PIX key for pix/payment_info/review_and_pay buttons." merchant_name: type: string example: "Minha Loja" description: "Merchant name shown on PIX/review_and_pay buttons." pix_type: type: string example: "PHONE" enum: [PHONE, EMAIL, CPF, CNPJ, EVP] description: "Type of PIX key provided in pix_key." currency: type: string example: "BRL" description: "Currency code (ISO 4217) for review_and_pay buttons." total_value: type: integer example: 2599 description: "Total amount in minor units (e.g., cents) for review_and_pay buttons." total_offset: type: integer example: 100 description: "Optional offset or discount amount in minor units." reference_id: type: string example: "ORDER-2024-001" description: "Reference identifier associated with the payment/order." items: type: array description: "Detailed order items for review_and_pay buttons." items: type: object required: - name - quantity - amount_value - amount_offset properties: name: type: string example: "Fone de ouvido" description: "Item name." quantity: type: integer example: 1 description: "Quantity of the item." amount_value: type: integer example: 7990 description: "Item value in minor units (e.g., cents)." amount_offset: type: integer example: 100 description: "Optional discount/offset in minor units for the item." id: type: string example: "BUTTONS_8A7B9C2D1E3F4A5B6C7D8E9F0A1B2C3D" description: "Optional custom message ID. If not provided, a random one will be generated." presence: type: integer example: 2000 description: "Milliseconds to simulate typing indicator before sending the message." duration: type: integer example: 10 description: "Ephemeral duration for the message (when applicable)." number_check: type: boolean example: true description: "Set to true to verify if the phone number is registered on WhatsApp before sending." context_info: $ref: "#/definitions/ContextInfo" FlowMessage: type: object description: "Native flow interactive message." required: - Phone - Buttons properties: Phone: type: string example: "5521971532700" description: "Recipient phone number with country code (without +) or group JID." Body: type: string example: "Complete your profile to unlock premium features" description: "Primary message text. Use this or Text/Message." Text: type: string example: "Complete your profile to unlock premium features" description: "Alternative body text." Message: type: string example: "Complete your profile to unlock premium features" description: "Legacy body text field." Caption: type: string example: "Let's get started" description: "Optional caption when using media headers." Footer: type: string example: "Powered by DigiGO" description: "Optional footer text." Id: type: string example: "FLOW_MSG_001" description: "Custom message ID. Auto-generated when omitted." Presence: type: integer example: 2000 description: "Typing simulation in milliseconds before sending." NumberCheck: type: boolean example: true description: "Verify that the recipient is registered on WhatsApp before sending." MessageVersion: type: integer format: int32 example: 3 description: "Native flow message version. Use the latest available version." MessageParams: type: object description: "Flow parameters as an object. Use MessageParams or MessageParamsJSON." additionalProperties: true example: flow_type: "registration" required_fields: ["name", "email"] MessageParamsJSON: type: string example: '{"flow_type":"registration"}' description: "Flow parameters represented as a JSON string." Header: type: object description: "Optional header with title, subtitle, and media." properties: Title: type: string example: "Complete your profile" Subtitle: type: string example: "Only takes 2 minutes" Media: type: object properties: Type: type: string enum: [image, video, document] example: "image" description: "Header media type." Url: type: string example: "https://example.com/header.png" description: "Media URL or base64 data URL." Caption: type: string example: "Preview" Filename: type: string example: "guide.pdf" MimeType: type: string example: "image/png" Buttons: type: array description: "Array of native flow buttons." minItems: 1 items: type: object required: - Name properties: Name: type: string example: "complete_profile" description: "Button identifier." ButtonParams: type: object description: "Button parameters as an object." additionalProperties: true example: display_text: "Complete Profile" flow_id: "123456789" ButtonParamsJSON: type: string example: '{"display_text":"Complete Profile","flow_id":"123456789"}' description: "Button parameters as JSON string." Params: type: object description: "Optional flow parameters object." additionalProperties: true example: mode: "draft" version: "3.0" ParamsJSON: type: string example: '{"mode":"published","version":"3.0"}' description: "Optional flow parameters JSON string." ContextInfo: $ref: "#/definitions/ContextInfo" CarouselMessage: type: object description: "Carousel message with multiple cards." required: - Phone - Message - Carousel properties: Phone: type: string example: "5521971532700" description: "Recipient phone number with country code (without +) or group JID." Message: type: string example: "Check out our featured products!" description: "Introductory text shown before the carousel cards." Carousel: type: array description: "Array of carousel card objects." minItems: 1 maxItems: 10 items: type: object required: - Text - Buttons properties: Text: type: string example: "Premium Wireless Headphones\n\n• Noise cancellation\n• 30h battery\n• Premium sound\n\n$299.99" description: "Card body text." MediaUrl: type: string example: "https://picsum.photos/600/400.jpg" description: "Optional media URL or base64 data URL." MediaType: type: string enum: [image, video, document] example: "image" description: "Media type required when MediaUrl is provided." Filename: type: string example: "Product_Guide.pdf" description: "Optional filename for document media." Caption: type: string example: "Best Seller!" description: "Optional media caption." Buttons: type: array description: "Card-specific buttons." minItems: 1 maxItems: 3 items: type: object required: - Label - Type properties: Id: type: string example: "buy_headphones" description: "Button identifier for reply/copy buttons." Label: type: string example: "Buy Now" description: "Button display text." Url: type: string example: "https://store.example.com/product/123" description: "Destination URL for url buttons." Type: type: string enum: [reply, url, copy, call] example: "url" description: "Button type." Id: type: string example: "CAROUSEL_MSG_001" description: "Custom message ID. Auto-generated when omitted." Presence: type: integer example: 2000 description: "Typing simulation in milliseconds before sending." NumberCheck: type: boolean example: true description: "Verify that the recipient is registered on WhatsApp before sending." ContextInfo: $ref: "#/definitions/ContextInfo" MessageSticker: type: object required: - Phone - Sticker properties: Phone: type: string example: "5521971532700" description: "Phone number with country code" Sticker: type: string example: "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=" description: "Sticker data as base64 data URL (data:image/webp;base64,xxx) or HTTP(S) URL (https://example.com/sticker.webp)" Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID" MimeType: type: string example: "image/webp" description: "Optional MIME type override (image/webp, image/jpeg, image/png, image/gif)" PngThumbnail: type: string format: byte description: "Optional PNG thumbnail as base64 string" example: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" MessageDocument: type: object required: - Phone - Document - FileName properties: Phone: type: string example: "5521971532700" description: "Phone number with country code" Document: type: string example: "data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsO..." description: "Document data as base64 data URL (data:application/pdf;base64,xxx) or HTTP(S) URL (https://example.com/document.pdf)" FileName: type: string example: "document.pdf" description: "Name of the document file with extension" Caption: type: string example: "Important document" description: "Optional caption for the document" Id: type: string example: "ABCDABCD1234" description: "Optional custom message ID" MimeType: type: string example: "application/pdf" description: "Optional MIME type override (application/pdf, application/msword, text/plain, etc.)" Presence: type: integer example: 3000 description: "Milliseconds to simulate typing indicator" Duration: type: integer example: 86400 description: "Message expiration time in seconds" EchoApi: type: boolean example: true description: "Optional. Set to true to force emission of API echo events for this specific message, regardless of global or per-session echo settings. When enabled, a synthetic Message event with Info.IsFromAPI=true will be emitted through your configured transports/webhook after the message is successfully sent. This allows individual message-level control over echo behavior, overriding both ECHO_API_MESSAGES_ENABLED (global) and the per-session echo_api_messages setting. Useful for selectively tracking specific API-sent messages through your event pipeline." ContextInfo: $ref: "#/definitions/ContextInfo" DeleteMessage: type: object required: - Id - Phone properties: Phone: type: string example: "5521971532700" Id: type: string example: "1234-abcd-21234" Markread: type: object required: - Id - Chat properties: Id: type: object example: ["AABBCC11223344", "DDEEFF55667788"] Chat: type: string example: 5491155553934.0:1@s.whatsapp.net Sender: type: string example: 5491155553111.0:1@s.whatsapp.net Pairphone: type: object required: - Phone properties: Phone: type: string example: "5491155553934" Checkuser: type: object required: - Phone properties: Phone: type: object example: ["5491155553934", "5521971532700"] Checkavatar: type: object required: - Phone - Preview properties: Phone: type: string description: "Phone number or JID to get profile picture for" example: "5491155553934" Preview: type: bool description: "If true, returns thumbnail/preview version. If false, returns full resolution picture" example: true IsCommunity: type: boolean description: "Set to true when getting profile picture of a WhatsApp Community (optional)" example: false CommonGID: type: string description: "Common group JID that you share with the target user. Allows getting profile picture of users through a shared group even if they have privacy settings that would normally prevent it. Format: 120363123456789012@g.us (optional)" example: "120363123456789012@g.us" InviteCode: type: string description: "Group invite code to query the profile photo of a group you haven't joined yet. Useful for previewing group information before joining (optional)" example: "ABC123XYZ456" PersonaID: type: string description: "Persona ID for getting profile pictures of Meta AI bots. Required when querying AI bot avatars (optional)" example: "ai-bot-persona-id" Webhook: type: object required: - WebhookURL properties: WebhookURL: type: string example: http://server/webhook WebhookSet: type: object required: - webhook - events properties: webhookurl: type: string description: The URL of the webhook example: "https://example.net/webhook" events: type: array items: type: string description: List of events to subscribe to. Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events) example: ["Message", "ReadReceipt", "GroupInfo", "Connected", "All"] WebhookUpdate: type: object properties: webhookurl: type: string description: The URL of the webhook example: "https://example.net/webhook" events: type: array items: type: string description: List of events to subscribe to. Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events) example: ["Message", "ReadReceipt", "GroupInfo", "Connected", "All"] Active: type: boolean description: Whether the webhook should be active or not example: true GroupLeave: type: object required: - GroupJID properties: GroupJID: type: string description: The JID of the group to leave (e.g., 120363312246943103@g.us) example: 120363312246943103@g.us GroupName: type: object required: - GroupJID - Name properties: GroupJID: type: string description: The JID of the group to rename example: 120363312246943103@g.us Name: type: string description: The new name for the group example: My New Group Name GroupTopic: type: object required: - GroupJID - Topic properties: GroupJID: type: string description: The JID of the group to set the topic for example: 120363312246943103@g.us Topic: type: string description: The new topic/description for the group example: Welcome to our project group! GroupAnnounce: type: object required: - GroupJID - Announce properties: GroupJID: type: string description: The JID of the group to set announce mode example: 120363312246943103@g.us Announce: type: boolean description: Whether to enable (true) or disable (false) announce mode example: true GroupJoin: type: object required: - Code properties: Code: type: string description: The invite code or link to join the group example: HffXhYmzzyJGec61oqMXiz GroupInviteInfo: type: object required: - Code properties: Code: type: string description: The group invite code to get information for example: HffXhYmzzyJGec61oqMXiz UpdateGroupParticipants: type: object required: - GroupJID - Action - Phone properties: GroupJID: type: string description: The JID of the group example: 120363312246943103@g.us Action: type: string description: Action to perform ("add" to add participants, "remove" to remove participants, "promote" to promote participants, "demote" to demote participants.) enum: [add, remove, promote, demote] example: add Phone: type: array items: type: string description: List of participant JIDs (e.g., 5491112345678@s.whatsapp.net or 5491112345678) example: ["5491112345678", "5491123456789@s.whatsapp.net"] CreateGroup: type: object required: - Name - Participants properties: Name: type: string description: The name for the new group example: "My New Group" Participants: type: array items: type: string description: List of participant phone numbers (without country code prefix symbols) example: ["5491112345678", "5491123456789"] GroupLocked: type: object required: - GroupJID - Locked properties: GroupJID: type: string description: The JID of the group to configure example: "120363312246943103@g.us" Locked: type: boolean description: Whether to lock the group (true) or unlock it (false). When locked, only admins can modify group info. example: true GroupEphemeral: type: object required: - GroupJID - Duration properties: GroupJID: type: string description: The JID of the group to configure ephemeral messages example: "120363312246943103@g.us" Duration: type: string description: Duration for disappearing messages. Use "24h" for 24 hours, "7d" for 7 days, "90d" for 90 days, or "off" to disable. enum: ["24h", "7d", "90d", "off"] example: "24h" RemoveGroupPhoto: type: object required: - GroupJID properties: GroupJID: type: string description: The JID of the group to remove the photo from example: "120363312246943103@g.us" SessionStatus: type: object description: "Current WhatsApp connection, session, and configuration state for the authenticated user" properties: id: type: string description: Unique identifier of the session/user example: "bec45bb93cbd24cbec32941ec3c93a12" name: type: string description: Display name associated with the session example: "Some User" avatar_url: type: string nullable: true description: Cached avatar URL if available (valid for 24h) example: "https://example.com/avatar.jpg" connected: type: boolean description: Whether the WhatsApp client currently has an active websocket connection example: true loggedIn: type: boolean description: Whether the WhatsApp session is authenticated example: true hasClient: type: boolean description: Whether an active WhatsMeow client instance exists for this session example: true connectionHealth: type: string description: High-level status indicator of the connection enum: [ "unknown", "no_client", "disconnected", "connected_not_logged", "connected", ] example: "connected" lastSuccessfulConnect: type: integer format: int64 description: Unix timestamp of the last successful connection event (0 if never connected) example: 1705312845 autoReconnectErrors: type: integer description: Number of automatic reconnect attempts that have failed consecutively example: 0 enableAutoReconnect: type: boolean description: Indicates if automatic reconnect is enabled for this session example: true expiration: type: integer format: int64 description: Number of seconds remaining until the session token expires example: 86400 token: type: string description: Authentication token for API access example: "d030sl9aDL39sl3075zz" jid: type: string description: WhatsApp JID currently associated with the session example: "5491155551122:12@s.whatsapp.net" webhook: type: string description: Configured webhook URL for outbound events example: "https://some.domain/webhook" events: type: string description: Event subscription filter applied to this session example: "All" proxy_url: type: string nullable: true description: Legacy proxy URL string kept for backward compatibility example: "" qrcode: type: string description: Base64 QR code when an authentication QR is pending example: "" skip_media_download: type: boolean description: Whether media downloads are disabled for this session example: false skip_groups: type: boolean description: Whether group messages should be skipped example: false skip_newsletters: type: boolean description: Whether newsletter messages should be skipped example: false skip_broadcasts: type: boolean description: Whether broadcast messages should be skipped example: false skip_own_messages: type: boolean description: Whether messages sent by this account should be skipped example: false echo_api_messages: type: boolean description: Whether API-sent messages should be echoed back through transports example: false skip_calls: type: boolean description: Whether call events should be skipped example: false call_reject_message: type: string description: Optional automated response message when rejecting calls example: "Sorry, I cannot take calls at the moment." call_reject_type: type: string description: Strategy used to reject calls (e.g. busy, decline) example: "busy" globalTransportSkips: $ref: "#/definitions/GlobalTransportSkipFlags" description: "Snapshot of the per-transport global dispatcher skip flags." isFromAPI: type: boolean description: "Reflects the Echo API configuration. When true, Info.IsFromAPI markers are emitted for API sends." example: false proxy_config: $ref: "#/definitions/ProxyConfig" s3_config: $ref: "#/definitions/S3Config" rabbitmq_config: $ref: "#/definitions/RabbitMQConfig" timestamp: type: integer format: int64 description: Unix timestamp when this status snapshot was generated example: 1705312845 required: - id - connected - loggedIn - hasClient - connectionHealth - timestamp ProxyConfig: type: object properties: enabled: type: boolean description: Whether proxy usage is enabled for this session example: false proxy_url: type: string nullable: true description: Proxy URL to be used when enabled (supports http/https/socks5) example: "http://proxy.example.com:8080" required: - enabled S3Config: type: object properties: enabled: type: boolean description: Whether S3 storage is enabled example: true endpoint: type: string description: S3 endpoint URL (leave empty for AWS S3) example: "https://s3.amazonaws.com" region: type: string description: S3 region example: "us-east-1" bucket: type: string description: S3 bucket name example: "my-whatsapp-media" access_key: type: string description: S3 access key ID example: "AKIAIOSFODNN7EXAMPLE" secret_key: type: string description: S3 secret access key example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" path_style: type: boolean description: Use path-style URLs (required for MinIO) example: false public_url: type: string description: Custom public URL for accessing files (optional, for CDN) example: "https://cdn.example.com" media_delivery: type: string description: Media delivery method enum: ["base64", "s3", "both"] example: "both" retention_days: type: integer description: Number of days to retain files (0 for no expiration) disable_acl: type: boolean description: Set to true for AWS S3 buckets with "Bucket owner enforced" Object Ownership example: true RabbitMQConfig: type: object properties: enabled: type: boolean description: Whether RabbitMQ publishing is enabled example: true url: type: string description: RabbitMQ connection URL in format amqp://username:password@host:port/vhost example: "amqp://guest:guest@localhost:5672/" exchange: type: string description: Exchange name for publishing events example: "whatsapp.events" exchange_type: type: string description: Exchange type for events (required when enabled) enum: ["topic", "direct", "fanout", "headers"] example: "topic" queue: type: string description: "Queue name pattern with dynamic placeholders. Use {user_id} and {event_type} for automatic queue creation per event type. Examples: 'user_{user_id}_main' (static) or 'user_{user_id}_event_{event_type}' (dynamic per event)" example: "user_{user_id}_event_{event_type}" queue_type: type: string description: Queue type for events (required when enabled) enum: ["classic", "quorum", "stream"] example: "classic" routing_key: type: string description: "Routing key pattern with dynamic placeholders. Use {user_id} and {event_type} for event-specific routing. Example: 'whatsapp.{user_id}.{event_type}' creates keys like 'whatsapp.abc123.Message'" example: "whatsapp.{user_id}.{event_type}" events: type: string description: 'Event types to publish (comma-separated or "All"). Available events include all 47 event types from Message, UndecryptableMessage, Receipt, MediaRetry, ReadReceipt, GroupInfo, JoinedGroup, Picture, BlocklistChange, Blocklist, Connected, Disconnected, ConnectFailure, KeepAliveRestored, KeepAliveTimeout, LoggedOut, ClientOutdated, TemporaryBan, StreamError, StreamReplaced, PairSuccess, PairError, QR, QRScannedWithoutMultidevice, PrivacySettings, PushNameSetting, UserAbout, AppState, AppStateSyncComplete, HistorySync, OfflineSyncCompleted, OfflineSyncPreview, CallOffer, CallAccept, CallTerminate, CallOfferNotice, CallRelayLatency, Presence, ChatPresence, IdentityChange, CATRefreshError, NewsletterJoin, NewsletterLeave, NewsletterMuteChange, NewsletterLiveUpdate, FBMessage, to All (which subscribes to all events). Event names are case-sensitive; CSV values with spaces are normalized (for example: "Message, Disconnected").' example: "Message,ReadReceipt,Connected,All" durable: type: boolean description: Whether the exchange and queue should be durable example: true auto_delete: type: boolean description: Whether the exchange and queue should auto-delete when unused example: false exclusive: type: boolean description: Whether the queue should be exclusive to this connection example: false no_wait: type: boolean description: Whether to use no-wait flag for faster operations example: false delivery_mode: type: integer description: Message delivery mode (1=non-persistent, 2=persistent) enum: [1, 2] example: 2 dead_letter_exchange: type: string description: Dead Letter Exchange name. Rejected or expired messages will be routed to this exchange. example: "dlx.whatsapp" dead_letter_routing_key: type: string description: Routing key for Dead Letter Exchange. Used when routing rejected/expired messages to DLQ. example: "dlq.events" message_ttl: type: integer format: int64 description: Message TTL (Time To Live) in milliseconds. Messages older than this will be discarded or sent to DLX if configured. example: 86400000 max_length: type: integer format: int64 description: Maximum number of messages in the queue. Overflow behavior depends on x-overflow setting. example: 100000 max_length_bytes: type: integer format: int64 description: Maximum total size of messages in the queue in bytes. example: 104857600 queue_arguments: type: object additionalProperties: true description: "Custom queue arguments as JSON object. Supports any RabbitMQ queue argument like x-overflow, x-queue-master-locator, etc." example: x-overflow: "reject-publish" x-queue-master-locator: "min-masters" exchange_arguments: type: object additionalProperties: true description: "Custom exchange arguments as JSON object. Supports any RabbitMQ exchange argument." example: {} connection_pool_size: type: integer description: "Size of the connection pool for RabbitMQ connections. Higher values allow more concurrent operations. Default: 50" example: 50 worker_count: type: integer description: "Number of concurrent workers for message publishing. Default: 100" example: 100 queue_buffer_size: type: integer description: "In-memory queue buffer size for event batching before publishing. Default: 100000" example: 100000 batch_size: type: integer description: "Number of events to batch together before publishing. Default: 1000" example: 1000 batch_timeout_ms: type: integer description: "Maximum time in milliseconds to wait before publishing a partial batch. Default: 100" example: 100 publish_timeout_ms: type: integer description: "Timeout in milliseconds for individual publish operations. Default: 5000" example: 5000 max_retries: type: integer description: "Maximum number of retry attempts for failed publish operations. Default: 3" example: 3 retry_delay_ms: type: integer description: "Delay in milliseconds between retry attempts. Default: 1000" example: 1000 SkipMediaConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to skip downloading media files during WhatsApp events. When enabled, events will only contain metadata without base64 content or S3 uploads, improving performance." example: true example: enabled: true SkipGroupsConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to skip processing messages from WhatsApp groups. When enabled, the system will ignore all messages from group chats, processing only direct messages. This can improve performance and reduce processing overhead for applications that don't need group functionality." example: true example: enabled: true SkipNewslettersConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to skip processing messages from WhatsApp newsletters. When enabled, the system will ignore all messages from newsletter channels, processing only direct messages and groups. This can improve performance and reduce processing overhead for applications that don't need newsletter functionality." example: true example: enabled: true SkipBroadcastsConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to skip processing messages from WhatsApp broadcasts and status updates. When enabled, the system will ignore all messages from broadcast lists and status updates, processing only direct messages, groups, and newsletters. This can improve performance and reduce processing overhead for applications that don't need broadcast functionality." example: true example: enabled: true SkipCallsConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to automatically reject incoming WhatsApp calls. When enabled, all incoming calls will be automatically rejected and an optional message will be sent to the caller." example: true reject_message: type: string description: "Optional message to send to the caller after automatically rejecting the call. If not provided, a default message will be used." example: "Sorry, I cannot take calls at the moment. Please send a message." reject_type: type: string description: "Type of call rejection to use when automatically rejecting calls." enum: ["busy", "declined", "unavailable"] example: "busy" example: enabled: true reject_message: "Sorry, I cannot take calls at the moment. Please send a message." reject_type: "busy" SkipOwnMessagesConfig: type: object required: - enabled properties: enabled: type: boolean description: "Whether to skip processing your own sent messages (IsFromMe: true). When enabled, the system will ignore all messages that were sent by you, processing only messages received from others. This can improve performance and reduce processing overhead for applications that don't need to track outgoing messages." example: true example: enabled: true MessageEdit: type: object required: - Id - Phone - Body properties: Id: type: string example: "90B2F8B13FAC8A9CF6B06E99C7834DC5" description: "Message ID to edit" Phone: type: string example: "5521971532700" description: "Phone number with country code" Body: type: string example: "This is the updated message" description: "New message content" ContextInfo: type: object description: "Optional context info for replies" properties: StanzaId: type: string example: "3EB06F9067F80BAB89FF" description: "Message ID to reply to" Participant: type: string example: "5521971532700@s.whatsapp.net" description: "JID of original message sender" IsForwarded: type: boolean example: true description: "Set to true to mark the message as forwarded. This is the preferred method for forwarding messages." MentionedJID: type: array items: type: string example: ["5521971532700@s.whatsapp.net", "5491155553934@s.whatsapp.net"] description: "Array of JIDs to mention in the message. Use full WhatsApp JID format (number@s.whatsapp.net)." MentionAll: type: boolean example: true description: "Set to true to mention all group members" GlobalTestEvent: type: object properties: event_type: type: string description: "Type of test event to send" example: "AdminTest" default: "TestEvent" user_id: type: string description: "User ID for the test event" example: "admin-test" default: "admin-test" user_token: type: string description: "User token for the test event (optional, defaults to user_id if not provided)" example: "admin-test-token" data: type: object description: "Custom data to include in the test event" additionalProperties: true example: { "test": true, "message": "This is a test event", "timestamp": 1705312845, } example: event_type: "AdminTest" user_id: "admin-test" user_token: "admin-test-token" data: test: true message: "This is a test event sent from the admin panel" CallRejectRequest: type: object required: - call_id - call_from - reject_type properties: call_id: type: string description: "The unique identifier of the call to reject" example: "call_12345_abcd" call_from: type: string description: "The JID (phone number) of the caller in WhatsApp format" example: "5521971532700@s.whatsapp.net" reject_type: type: string description: "The type of rejection to send" enum: ["busy", "declined", "unavailable"] example: "busy" message: type: string description: "Optional custom message to send to the caller after rejecting" example: "Sorry, I'm currently busy and cannot take your call right now. I'll call you back later." example: call_id: "call_12345_abcd" call_from: "5521971532700@s.whatsapp.net" reject_type: "busy" message: "Sorry, I'm currently busy and cannot take your call right now. I'll call you back later." GetLIDRequest: type: object required: - phone properties: phone: type: string description: "Phone number or JID to convert to LID" example: "5521971532700@s.whatsapp.net" GetJIDFromLIDRequest: type: object required: - lid properties: lid: type: string description: "LID (Link ID) to convert to phone/JID" example: "2:abcd1234efgh5678@lid" LIDResponse: type: object properties: success: type: boolean example: true phone: type: string description: "Original phone/JID provided" example: "5521971532700@s.whatsapp.net" lid: type: string description: "Generated LID (Link ID)" example: "2:abcd1234efgh5678@lid" created_at: type: integer format: int64 description: "Unix timestamp when LID was created" example: 1640995200 message: type: string description: "Success message" example: "LID retrieved successfully" JIDFromLIDResponse: type: object properties: success: type: boolean example: true lid: type: string description: "Original LID provided" example: "2:abcd1234efgh5678@lid" phone: type: string description: "Phone/JID corresponding to the LID" example: "5521971532700@s.whatsapp.net" created_at: type: integer format: int64 description: "Unix timestamp when LID was created" example: 1640995200 message: type: string description: "Success message" example: "Phone/JID retrieved successfully" LIDMapping: type: object properties: id: type: integer description: "Unique mapping ID" example: 1 phone: type: string description: "Phone number or JID" example: "5521971532700@s.whatsapp.net" lid: type: string description: "Corresponding LID (Link ID)" example: "2:abcd1234efgh5678@lid" created_at: type: integer format: int64 description: "Unix timestamp when mapping was created" example: 1640995200 last_used: type: integer format: int64 description: "Unix timestamp when mapping was last used" example: 1640995500 usage_count: type: integer description: "Number of times this mapping has been used" example: 5 LIDMappingsResponse: type: object properties: success: type: boolean example: true total: type: integer description: "Total number of mappings for the user" example: 150 limit: type: integer description: "Maximum number of mappings returned" example: 100 offset: type: integer description: "Number of mappings skipped" example: 0 mappings: type: array items: $ref: "#/definitions/LIDMapping" description: "Array of LID mappings" message: type: string description: "Success message" example: "LID mappings retrieved successfully" StatusText: type: object required: - text properties: text: type: string description: "Text content for the status (maximum 650 characters)" maxLength: 650 example: "Hello World! This is my status update 🌟" background_color: type: string description: "Background color in ARGB decimal format. Use https://argb-int-calculator.netlify.app/ to generate" example: "4294967295" text_color: type: string description: "Text color in ARGB decimal format. Use https://argb-int-calculator.netlify.app/ to generate" example: "4278190080" font: type: integer description: "Font type (0: SYSTEM, 1: SYSTEM_TEXT, 2: FB_SCRIPT, 6: SYSTEM_BOLD, 7: MORNINGBREEZE_REGULAR, 8: CALISTOGA_REGULAR, 9: EXO2_EXTRABOLD, 10: COURIERPRIME_BOLD)" minimum: 0 maximum: 10 example: 0 id: type: string description: "Optional custom message ID" example: "custom-status-id-123" example: text: "Hello World! This is my status update 🌟" background_color: "4294967295" text_color: "4278190080" font: 7 id: "custom-status-id-123" StatusImage: type: object required: - image properties: image: type: string description: "Base64 encoded image data (data:image/jpeg;base64,...) or HTTP(S) URL. Supported formats: JPEG, PNG, GIF, WebP" example: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." caption: type: string description: "Optional caption text for the image" example: "Beautiful sunset today! 🌅" id: type: string description: "Optional custom message ID" example: "status-image-123" example: image: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." caption: "Beautiful sunset today! 🌅" id: "status-image-123" StatusVideo: type: object required: - video properties: video: type: string description: "Base64 encoded video data (data:video/mp4;base64,...) or HTTP(S) URL. Supported formats: MP4, 3GPP. Requires H.264 video codec and AAC audio codec" example: "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE..." caption: type: string description: "Optional caption text for the video" example: "Check out this amazing video! 🎬" id: type: string description: "Optional custom message ID" example: "status-video-123" example: video: "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDE..." caption: "Check out this amazing video! 🎬" id: "status-video-123" StatusAudio: type: object required: - audio properties: audio: type: string description: "Base64 encoded audio data (data:audio/ogg;base64,...) or HTTP(S) URL. Supported formats: OGG with Opus codec, MP3, M4A" example: "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABK/wAAAAAAAIAuABBT..." caption: type: string description: "Optional caption text for the audio" example: "Listen to this! 🎵" ptt: type: boolean description: "Set to true to send as voice note (Push-To-Talk), false for regular audio" default: false example: false id: type: string description: "Optional custom message ID" example: "status-audio-123" example: audio: "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABK/wAAAAAAAIAuABBT..." caption: "Listen to this! 🎵" ptt: false id: "status-audio-123" ChangePushNameRequest: type: object required: - push_name properties: push_name: type: string description: "New push name for the user" example: "John Doe" example: push_name: "John Doe" SetMyStatusRequest: type: object required: - status properties: status: type: string description: "New status message for the user" example: "Working from home 🏠" example: status: "Working from home 🏠" SetProfilePhoto: type: object required: - Image properties: Image: type: string description: | Image data to set as profile photo. Accepts two formats: - **Base64 data URL**: `data:image/jpeg;base64,/9j/4AAQ...` (inline JPEG encoded as data URL) - **HTTP/HTTPS URL**: `https://example.com/photo.jpg` (remote image, downloaded server-side) **Image requirements:** - Format: JPEG only (`.jpg` / `.jpeg`). PNG, GIF, WebP are NOT accepted by WhatsApp - Maximum resolution: 640x640 pixels - Recommended aspect ratio: 1:1 (square) - Recommended file size: under 5MB example: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..." example: Image: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..." BusinessProfileRequest: type: object required: - phone properties: phone: type: string description: "Phone number of the WhatsApp Business account to get profile information" example: "5491155553934" example: phone: "5491155553934" UserInfoImprovedResponse: type: object properties: code: type: integer example: 200 data: type: object properties: jid: type: string description: "User's WhatsApp JID" example: "5491155553934@s.whatsapp.net" status: type: string description: "User's current status message" example: "Available for work 💼" picture_id: type: string description: "Profile picture ID" example: "1582328807" verified_name: type: string description: "Verified business name (if available)" example: "Company Name" devices: type: array items: type: object properties: user: type: string description: "User number" example: "5491155553934" agent: type: string description: "Device agent ID" example: "25" device: type: string description: "Device platform name" example: "CHROME" server: type: string description: "Server domain" example: "s.whatsapp.net" ad: type: string description: "Advertisement string" example: "5491155553934.0:6@s.whatsapp.net" success: type: boolean example: true example: code: 200 data: jid: "5491155553934@s.whatsapp.net" status: "Available for work 💼" picture_id: "1582328807" verified_name: "Company Name" devices: - user: "5491155553934" agent: "25" device: "CHROME" server: "s.whatsapp.net" ad: "5491155553934.0:6@s.whatsapp.net" - user: "5491155553934" agent: "15" device: "DESKTOP" server: "s.whatsapp.net" ad: "5491155553934.0:0@s.whatsapp.net" success: true # Community Schemas LinkGroupRequest: type: object required: - parent_jid - child_jid properties: parent_jid: type: string description: "JID of the parent community" example: "120363025246487852@newsletter" child_jid: type: string description: "JID of the child group to link" example: "120363312246943103@g.us" example: parent_jid: "120363025246487852@newsletter" child_jid: "120363312246943103@g.us" UnlinkGroupRequest: type: object required: - parent_jid - child_jid properties: parent_jid: type: string description: "JID of the parent community" example: "120363025246487852@newsletter" child_jid: type: string description: "JID of the child group to unlink" example: "120363312246943103@g.us" example: parent_jid: "120363025246487852@newsletter" child_jid: "120363312246943103@g.us" LinkedGroupsRequest: type: object required: - community_jid properties: community_jid: type: string description: "JID of the community" example: "120363025246487852@newsletter" example: community_jid: "120363025246487852@newsletter" LinkedGroupsResponse: type: object properties: success: type: boolean example: true community_jid: type: string example: "120363025246487852@newsletter" linked_groups: type: array items: type: string description: "Array of linked group JIDs" example: ["120363312246943103@g.us", "120363417042313103@g.us"] count: type: integer example: 2 description: "Number of linked groups" example: success: true community_jid: "120363025246487852@newsletter" linked_groups: ["120363312246943103@g.us", "120363417042313103@g.us"] count: 2 GroupRequestsRequest: type: object required: - group_jid properties: group_jid: type: string description: "JID of the group to get join requests for" example: "120363312246943103@g.us" example: group_jid: "120363312246943103@g.us" GroupRequestsResponse: type: object properties: success: type: boolean example: true group_jid: type: string example: "120363312246943103@g.us" requests: type: array items: type: object properties: jid: type: string example: "5491155553934@s.whatsapp.net" request_time: type: integer format: int64 example: 1640995200 description: "Unix timestamp when request was made" description: "Array of pending join requests" count: type: integer example: 3 description: "Number of pending requests" example: success: true group_jid: "120363312246943103@g.us" requests: - jid: "5491155553934@s.whatsapp.net" request_time: 1640995200 - jid: "5521971532700@s.whatsapp.net" request_time: 1640995300 count: 2 UpdateGroupRequestsRequest: type: object required: - group_jid - action - participants properties: group_jid: type: string description: "JID of the group" example: "120363312246943103@g.us" action: type: string enum: [approve, reject] description: "Action to perform on join requests" example: "approve" participants: type: array items: type: string description: "Array of participant JIDs to approve/reject" example: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] example: group_jid: "120363312246943103@g.us" action: "approve" participants: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] CreateCommunityRequest: type: object required: - name properties: name: type: string description: "Name of the new community" example: "My Community" description: type: string description: "Optional community description" example: "A community for our organization" initial_groups: type: array items: type: string description: "Optional array of group JIDs to link immediately" example: ["120363312246943103@g.us", "120363417042313103@g.us"] example: name: "My Community" description: "A community for our organization" initial_groups: ["120363312246943103@g.us"] CreateCommunityResponse: type: object properties: success: type: boolean example: true message: type: string example: "Community created successfully" community_jid: type: string example: "120363025246487852@newsletter" name: type: string example: "My Community" linked_groups: type: array items: type: string description: "Array of initially linked group JIDs" example: ["120363312246943103@g.us"] linked_count: type: integer example: 1 description: "Number of groups linked during creation" example: success: true message: "Community created successfully" community_jid: "120363025246487852@newsletter" name: "My Community" linked_groups: ["120363312246943103@g.us"] linked_count: 1 CommunityAnnouncementRequest: type: object required: - community_jid - message properties: community_jid: type: string description: "JID of the community" example: "120363025246487852@newsletter" message: type: string description: "Announcement message text" example: "Important community announcement for all members" example: community_jid: "120363025246487852@newsletter" message: "Important community announcement for all members" CommunityAnnouncementResponse: type: object properties: success: type: boolean example: true message: type: string example: "Announcement sent successfully" community_jid: type: string example: "120363025246487852@newsletter" announcement_text: type: string example: "Important community announcement for all members" sent_to_groups: type: integer example: 3 description: "Number of linked groups that received the announcement" example: success: true message: "Announcement sent successfully" community_jid: "120363025246487852@newsletter" announcement_text: "Important community announcement for all members" sent_to_groups: 3 # Business Schemas ResolveBusinessLinkRequest: type: object required: - business_link properties: business_link: type: string description: "WhatsApp Business message link to resolve" example: "https://wa.me/message/ABCDEFG123456" example: business_link: "https://wa.me/message/ABCDEFG123456" BusinessLinkInfo: type: object properties: success: type: boolean example: true business_link: type: string example: "https://wa.me/message/ABCDEFG123456" business_jid: type: string example: "5491155553934@s.whatsapp.net" business_name: type: string example: "My Business" verified: type: boolean example: true description: "Whether the business is verified" category: type: string example: "Retail" description: type: string example: "Premium retail store" website: type: string example: "https://mybusiness.com" email: type: string example: "contact@mybusiness.com" address: type: string example: "123 Main St, City, Country" example: success: true business_link: "https://wa.me/message/ABCDEFG123456" business_jid: "5491155553934@s.whatsapp.net" business_name: "My Business" verified: true category: "Retail" description: "Premium retail store" ContactQRRequest: type: object required: - phone properties: phone: type: string description: "Phone number to generate QR code for" example: "5491155553934" revoke: type: boolean description: "Whether to revoke existing QR codes before generating new one" example: false default: false example: phone: "5491155553934" revoke: false ContactQRResponse: type: object properties: success: type: boolean example: true phone: type: string example: "5491155553934" qr_link: type: string example: "https://wa.me/qr/ABCDEFG123456" description: "QR code link that can be used to add contact or start conversation" revoked_previous: type: boolean example: false description: "Whether previous QR codes were revoked" example: success: true phone: "5491155553934" qr_link: "https://wa.me/qr/ABCDEFG123456" revoked_previous: false BotInfo: type: object properties: jid: type: string example: "5491155553934@s.whatsapp.net" name: type: string example: "Support Bot" description: type: string example: "Automated customer support assistant" verified: type: boolean example: true example: jid: "5491155553934@s.whatsapp.net" name: "Support Bot" description: "Automated customer support assistant" verified: true BotProfilesRequest: type: object required: - bot_jids properties: bot_jids: type: array items: type: string description: "Array of bot JIDs to get profiles for" example: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] example: bot_jids: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] BotProfileInfo: type: object properties: jid: type: string example: "5491155553934@s.whatsapp.net" name: type: string example: "Support Bot" description: type: string example: "Automated customer support assistant" verified: type: boolean example: true avatar_url: type: string example: "https://example.com/bot-avatar.jpg" capabilities: type: array items: type: string example: ["messaging", "automation", "customer_support"] commands: type: array items: type: object properties: command: type: string example: "/help" description: type: string example: "Show available commands" description: "Available bot commands" example: jid: "5491155553934@s.whatsapp.net" name: "Support Bot" description: "Automated customer support assistant" verified: true avatar_url: "https://example.com/bot-avatar.jpg" capabilities: ["messaging", "automation"] commands: - command: "/help" description: "Show available commands" SendOrderRequest: type: object required: - phone - items properties: phone: type: string description: "Phone number of the business" example: "5491155553934" items: type: array items: type: object required: - name - quantity - price properties: name: type: string example: "Product Name" description: "Name of the product" quantity: type: integer example: 2 description: "Quantity of the product" price: type: number format: float example: 19.99 description: "Price per unit" currency: type: string example: "USD" default: "USD" description: "Currency code (ISO 4217)" image_url: type: string example: "https://example.com/product.jpg" description: "Optional product image URL" description: "Array of order items" notes: type: string description: "Optional order notes or special instructions" example: "Please deliver in the morning" example: phone: "5491155553934" items: - name: "Product A" quantity: 2 price: 19.99 currency: "USD" - name: "Product B" quantity: 1 price: 29.99 currency: "USD" notes: "Please deliver in the morning" OrderResponse: type: object properties: success: type: boolean example: true message: type: string example: "Order message sent successfully" phone: type: string example: "5491155553934" order_id: type: string example: "ORD123456789" description: "Generated order ID" items_count: type: integer example: 2 description: "Number of items in the order" total_amount: type: number format: float example: 69.97 description: "Total order amount" example: success: true message: "Order message sent successfully" phone: "5491155553934" order_id: "ORD123456789" items_count: 2 total_amount: 69.97 # Device Schemas UserDevicesRequest: type: object required: - jids properties: jids: type: array items: type: string description: "Array of user JIDs to get device information for" example: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] example: jids: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] DeviceInfo: type: object properties: jid: type: string example: "5491155553934@s.whatsapp.net" description: "User JID" devices: type: array items: type: object properties: device_id: type: integer example: 0 description: "Device ID (0 for main device)" platform: type: string example: "CHROME" description: "Device platform (CHROME, SAFARI, FIREFOX, EDGE, DESKTOP, etc.)" description: "Array of devices for this user" example: jid: "5491155553934@s.whatsapp.net" devices: - device_id: 0 platform: "CHROME" - device_id: 1 platform: "DESKTOP" LinkedDevicesResponse: type: object properties: success: type: boolean example: true linked_devices: type: array items: type: object properties: device_id: type: integer example: 0 platform: type: string example: "CHROME" connected: type: boolean example: true description: "Array of linked devices for current user" count: type: integer example: 2 description: "Number of linked devices" example: success: true linked_devices: - device_id: 0 platform: "CHROME" connected: true - device_id: 1 platform: "DESKTOP" connected: true count: 2 DevicePlatformRequest: type: object required: - device_id properties: device_id: type: integer description: "Device ID to get platform for" example: 0 example: device_id: 0 DevicePlatformResponse: type: object properties: success: type: boolean example: true device_id: type: integer example: 0 platform: type: string example: "CHROME" description: "Platform name (CHROME, SAFARI, FIREFOX, EDGE, DESKTOP, IOS, ANDROID, etc.)" example: success: true device_id: 0 platform: "CHROME" # Privacy Schemas SetPrivacySettingRequest: type: object required: - setting - value properties: setting: type: string enum: [ group_add, last_seen, status, profile, read_receipts, online, call_add, ] description: "Privacy setting to update" example: "last_seen" value: type: string enum: [all, contacts, contact_blacklist, none] description: "Privacy value (all=everyone, contacts=contacts only, contact_blacklist=contacts except, none=nobody)" example: "contacts" users: type: array items: type: string description: "Optional array of user JIDs for blacklist/whitelist (not currently supported in API)" example: ["5491155553934@s.whatsapp.net"] example: setting: "last_seen" value: "contacts" PrivacySettingsResponse: type: object properties: success: type: boolean example: true privacy_settings: type: object properties: group_add: type: string example: "contacts" description: "Who can add you to groups" last_seen: type: string example: "contacts" description: "Who can see your last seen" status: type: string example: "contacts" description: "Who can see your status updates" profile: type: string example: "contacts" description: "Who can see your profile photo" read_receipts: type: string example: "all" description: "Whether to send read receipts" online: type: string example: "all" description: "Who can see when you're online" call_add: type: string example: "contacts" description: "Who can call you" example: success: true privacy_settings: group_add: "contacts" last_seen: "contacts" status: "contacts" profile: "contacts" read_receipts: "all" online: "all" call_add: "contacts" DisappearingTimerRequest: type: object required: - timer properties: timer: type: string enum: ["24h", "7d", "90d", "off"] description: "Disappearing message timer duration" example: "24h" example: timer: "24h" UpdateBlocklistRequest: type: object required: - action - users properties: action: type: string enum: [block, unblock] description: "Action to perform (block or unblock)" example: "block" users: type: array items: type: string description: "Array of phone numbers or JIDs to block/unblock" example: ["5491155553934", "5521971532700@s.whatsapp.net"] example: action: "block" users: ["5491155553934", "5521971532700"] BlocklistResponse: type: object properties: success: type: boolean example: true blocked_contacts: type: array items: type: string description: "Array of blocked contact JIDs" example: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] count: type: integer example: 2 description: "Number of blocked contacts" example: success: true blocked_contacts: ["5491155553934@s.whatsapp.net", "5521971532700@s.whatsapp.net"] count: 2 StatusPrivacyResponse: type: object properties: success: type: boolean example: true status_privacy: type: string example: "contacts" description: "Current status privacy setting (all, contacts, contact_blacklist, or none)" description: type: string example: "Status privacy setting (all, contacts, contact_blacklist, or none)" example: success: true status_privacy: "contacts" description: "Status privacy setting (all, contacts, contact_blacklist, or none)" components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: token AdminAuth: type: apiKey in: header name: Authorization security: - ApiKeyAuth: []