openapi: 3.0.0
info:
  title: DINASTIAPI
  description: "DINASTIAPI implements a multi user and multi device REST API for WhatsApp.\n\n<h2>Authentication</h2><ul><li>Standard Endpoints: Include the token header with a valid user token (matches tokens stored in the users database table).</li><li>Admin Endpoints: Use the Authorization header with the admin token (set in .env as DINASTIAPI_ADMIN_TOKEN).</li></ul><h2>Admin Setup:</h2>You can manage users and do some tests by using the builtin dashboard [here](/dashboard).<h3>Add a Sample User via API</h3>Run this command to create a test user:<pre><code>curl -X POST http://localhost:8080/admin/users \\ \n-H \"Authorization: $DINASTIAPI_ADMIN_TOKEN\" \\ \n-H \"Content-Type: application/json\" \\ \n-d '{\"name\": \"John\", \"token\": \"Z1234ABCCXD\"}' </code> </pre>\n\n<h2>Webhook Configuration</h2>To receive WhatsApp messages:<ul><li>Host your own server (to process incoming messages).</li><li>Set its URL as the webhook via the [webhook](#Webhook) API call.</li></ul><h2>Phone number format:</h2><ul><li>Required: Country code (e.g. <b>5491155553934</b> for Argentina</li><li>Do not prefix with a plus sign (+), as natively whatsapp requires no plus sign prefix.</li></ul>"
  version: "1.2.6"
  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 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\n<b>API Echo Messages</b><br/>When the global flag <code>ECHO_API_MESSAGES_ENABLED</code> is true and the per-session echo setting is enabled, every successful API send emits a synthetic <code>Message</code> event through your configured transports/webhook. These events include the <code>Info.IsFromAPI: true</code> 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\n<b>Per-Message Echo Control (EchoApi Field)</b><br/>All send endpoints support an optional <code>EchoApi</code> boolean field that provides <b>message-level control</b> over echo behavior. When set to <code>true</code>, the message will emit an API echo event <b>regardless</b> of global (<code>ECHO_API_MESSAGES_ENABLED</code>) or per-session (<code>echo_api_messages</code>) 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
      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 <code>Info</code> structure includes <code>IsFromAPI: true</code>
        - The emitted event rides the same media/filters pipeline as regular messages.

        Requirements:
        - Global kill switch <code>ECHO_API_MESSAGES_ENABLED</code> must be <code>true</code>.
        - This endpoint toggles the per-session setting stored on the user.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enabled:
                  type: boolean
                  example: true
                  description: "Enable or disable API message echo for this session."
      responses:
        200:
          description: Echo API messages configuration updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  EchoAPIMessages:
                    type: boolean
                    example: true
                  Details:
                    type: string
                    example: Echo API messages configuration updated successfully
        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
      description: |
        Retrieves whether API message echo is enabled for this session.

        Note: The global kill switch <code>ECHO_API_MESSAGES_ENABLED</code> must be <code>true</code> 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:
                type: object
                properties:
                  EchoAPIMessages:
                    type: boolean
                    example: true
                  Details:
                    type: string
                    example: Echo API messages configuration retrieved successfully
        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 DinastiAPI 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",
                          "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 DinastiAPI user account
      description: Create a new DinastiAPI 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.
      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
                  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"
                    accessKey: "***"
                    pathStyle: true
                    publicUrl: "https://s3.amazonaws.com"
                    mediaDelivery: "both"
                    retentionDays: 30
                    disableAcl: true
                  rabbitmqConfig:
                    enabled: true
                    url: "amqp://guest:guest@localhost:5672/"
                    events: "All"
                    exchange: "whatsapp.events"
                    exchangeType: "topic"
                    queue: "whatsapp.user.{user_id}"
                    queueType: "classic"
                    routingKey: "whatsapp.{event_type}"
                    durable: true
                    autoDelete: false
                    exclusive: false
                    noWait: false
                    deliveryMode: 2
                  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/users/{id}:
    get:
      tags:
        - Admin
      summary: Get specific user by ID
      description: Retrieve detailed information about a specific DinastiAPI 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",
                          "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: "dinastiapi-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@dinastiapi.com"
                  documentation_url:
                    type: string
                    format: uri
                    description: Documentation URL
                    example: "https://github.com/guilhermejansen/use-dinastiapi"
              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": "dinastiapi-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@dinastiapi.com",
                  "documentation_url": "https://github.com/DinastIA-UK/use-dinastiapi",
                }
        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": "120363144038483540@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: dinastiapi-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": "dinastiapi-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: dinastiapi-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": "dinastiapi-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: Refresh and clean up session without disconnection
      description: "**Session Refresh - Clean Memory Without Reconnection**\n\nPerforms a session cleanup and refresh operation while maintaining the active connection. This is a **maintenance operation** that:\n\n- ✅ **Preserves** your active WebSocket connection\n- ✅ **Maintains** your login session and credentials  \n- ✅ **Cleans up** memory leaks and stale data\n- ✅ **Refreshes** internal session state\n- ✅ **No QR code required** - session remains active\n- ✅ **No reconnection needed** - WebSocket stays connected\n\n**What happens during refresh:**\n1. Cleans up accumulated memory and cached data\n2. Refreshes internal session management structures\n3. Validates and updates session metadata\n4. Maintains all active connections and subscriptions\n5. Preserves message history and chat state\n\n**Use Cases:**\n- Periodic maintenance to prevent memory leaks\n- Resolve session inconsistencies without full reconnection\n- Clean up after extended periods of high message volume\n- Refresh session after configuration changes\n- Troubleshoot connection issues without losing authentication\n\n**Benefits:**\n- Zero downtime - no disconnection occurs\n- Instant operation - no waiting for reconnection\n- Maintains message continuity\n- Resolves memory-related performance issues\n\n**Comparison with other endpoints:**\n- Use [disconnect](#/Session/post_session_disconnect) for temporary suspension (stops message flow)\n- Use [logout](#/Session/post_session_logout) for complete termination (requires QR)\n- Use `refresh` for maintenance while staying connected (no interruption)"
      security:
        - ApiKeyAuth: []
      responses:
        200:
          description: Session refreshed successfully
          content:
            application/json:
              schema:
                example:
                  {
                    "code": 200,
                    "data":
                      {
                        "Details": "Session refreshed successfully",
                        "timestamp": "2024-01-15T10:30:00Z",
                      },
                    "success": true,
                  }
        400:
          description: Bad request - refresh not possible
          content:
            application/json:
              schema:
                example:
                  {
                    "code": 400,
                    "error": "Cannot refresh session - not connected",
                    "success": false,
                  }
        500:
          description: Internal server error during refresh
          content:
            application/json:
              schema:
                example:
                  {
                    "code": 500,
                    "error": "Session refresh failed",
                    "success": 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",
                        "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":
                      {
                        "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,
                      },
                    "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
  /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/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/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":
                      {
                        "5491122223333@s.whatsapp.net":
                          {
                            "BusinessName": "",
                            "FirstName": "",
                            "Found": true,
                            "FullName": "",
                            "PushName": "FOP2",
                          },
                        "549113334444@s.whatsapp.net":
                          {
                            "BusinessName": "",
                            "FirstName": "",
                            "Found": true,
                            "FullName": "",
                            "PushName": "Guilherme Jansen",
                          },
                      },
                  }
  /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. ContextInfo is optional and used when repyling to some message. StanzaId is the message id we are replying to and participant who wrote that message. If sending a new message, ContextInfo can be ommited altogether.
      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
              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 DinastiAPI"
                  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

        **Use Cases:**
        - After device settings change
        - Periodic sync to ensure data consistency
        - Recover from sync issues
        - 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
      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"
        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": "dinastiapi.global",
                        "queue": "dinastiapi.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": "dinastiapi.global",
                        "queue": "dinastiapi.events",
                        "exchangeType": "topic",
                        "queueType": "classic",
                        "routingKey": "events.#",
                        "durable": true,
                        "autoDelete": false,
                        "deliveryMode": 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": "dinastiapi.global",
                            "queue": "dinastiapi.events",
                          },
                      },
                  }
        401:
          description: Unauthorized - Admin token required
          content:
            application/json:
              schema:
                example: { "error": "unauthorized - admin token required" }
  /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 <code>Authorization: Bearer &lt;admin_token&gt;</code> to receive the full firehose.
        - Or reuse a short-lived session token issued by <code>POST /admin/events/session</code> via the <code>session</code> query parameter.

        **Event Delivery**
        - Responses use the SSE framing (`id`, `event`, `data`) with <code>text/event-stream</code> content type.
        - The <code>data</code> field carries a JSON-encoded <code>MonitoringEvent</code>.
        - 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 <code>since_id</code> / <code>since_time</code>.
      security:
        - AdminAuth: []
      parameters:
        - name: session
          in: query
          description: Optional monitoring session token issued by <code>POST /admin/events/session</code>. 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., <code>message.sent</code>, <code>group.update</code>)
          required: false
          schema:
            type: string
          example: "message.sent"
        - name: status
          in: query
          description: Filter by processing status (<code>pending</code>, <code>processing</code>, <code>delivered</code>, <code>failed</code>)
          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 <code>since_id</code> or <code>since_time</code> 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 <code>true</code> 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 <code>data</code> line contains a JSON encoded <code>MonitoringEvent</code>.
              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 <code>POST /admin/events/session</code>.
          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., <code>message.sent</code>, <code>message.failed</code>)
          required: false
          schema:
            type: string
          example: "message.failed"
        - name: status
          in: query
          description: Filter by processing status (<code>pending</code>, <code>processing</code>, <code>delivered</code>, <code>failed</code>)
          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 <code>true</code> 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 <code>since_id</code> 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 <code>MONITORING_STORAGE_ENABLED</code> is <code>false</code> 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 <code>MONITORING_RETENTION_DAYS</code> 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 <code>monitoring_events</code>.
                  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 <code>session</code> query parameter.

        **Typical flow**
        1. Admin dashboard calls this endpoint with an optional filter.
        2. Use the returned <code>session_token</code> when connecting to <code>/admin/events/stream</code>.
        3. Non-admin tokens are limited to the <code>user_id</code> 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"
    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"

  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 <code>raw</code> 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 <code>failed</code>"
        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 <code>Info.IsFromAPI</code>."
      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)"
      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
          disableACL:
            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
          host:
            type: string
            example: "localhost"
          port:
            type: integer
            example: 5672
          username:
            type: string
            example: "***"
          vhost:
            type: string
            example: "/"
          exchange:
            type: string
            example: "whatsapp.events"
          exchange_type:
            type: string
            example: "topic"
          routing_key:
            type: string
            example: "whatsapp.{event_type}"
          queue:
            type: string
            example: "whatsapp.user.{user_id}"
          queue_type:
            type: string
            example: "classic"
          durable:
            type: boolean
            example: true
          auto_delete:
            type: boolean
            example: false
          events:
            type: array
            items:
              type: string
            example: ["Message", "ReadReceipt"]
      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'"
      echoApiMessages:
        type: boolean
        example: false
        description: "Enable synthetic Message events for messages sent via API. Requires global <code>ECHO_API_MESSAGES_ENABLED=true</code>."
      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"]

      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
        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"
          accessKey:
            type: string
            example: "1234567890"
          secretKey:
            type: string
            example: "1234567890"
          pathStyle:
            type: boolean
            example: true
            description: "Enable path style for the user, default is false"
          publicURL:
            type: string
            example: "https://s3.amazonaws.com"
            description: "Public URL for the user"
          mediaDelivery:
            type: string
            example: "both"
            description: "Media delivery type for the user, default is both"
          retentionDays:
            type: integer
            example: 30
          disableACL:
            type: boolean
            example: true
            description: "Set to true for AWS S3 buckets with 'Bucket owner enforced' Object Ownership"
      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)"
          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)"
      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"]
  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 DinastiAPI 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"
  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 DinastiAPI"
        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 DinastiAPI"
        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"
      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)
        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
  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 🏠"
  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: []
