{
  "manifest_version": "1.0.0",
  "template": {
    "id": "574011c7-1e22-428f-9eba-016809ea297b",
    "slug": "waha-secure-with-webhook",
    "name": "WAHA Secure with Webhook",
    "description": "Secure WAHA for Railway with API auth, storage, and webhooks",
    "url": "https://railway.com/deploy/waha-secure-with-webhook",
    "upstream": {
      "image": "devlikeapro/waha:latest"
    }
  },
  "services": [
    {
      "name": "WAHA Secure with Webhook",
      "source": {
        "image": "devlikeapro/waha:latest"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "WAHA_API_KEY",
      "service": "WAHA Secure with Webhook",
      "description": "API key used to secure WAHA’s REST API. Clients must send it in the X-Api-Key header. WAHA accepts either a plain secret or a sha512:-prefixed hash, and the hash form is the recommended production setup.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "WAHA_BASE_URL",
      "service": "WAHA Secure with Webhook",
      "description": "Base URL used to build the media.url field in webhook events. ",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "WAHA_HOOK_URL",
      "service": "WAHA Secure with Webhook",
      "description": "Webhook destination WAHA posts events to. The official docs document this setting as WHATSAPP_HOOK_URL; it defines where subscribed webhook events are delivered.",
      "secret": false,
      "strategy": "default",
      "default": "http://backend:8080/webhook"
    },
    {
      "key": "WAHA_PRINT_QR",
      "service": "WAHA Secure with Webhook",
      "description": "Controls whether login QR codes are printed into the service logs. Set it to False to keep Railway logs cleaner.",
      "secret": false,
      "strategy": "default",
      "default": "False"
    },
    {
      "key": "WAHA_LOG_LEVEL",
      "service": "WAHA Secure with Webhook",
      "description": "Controls log verbosity. Supported levels are error, warn, info, debug, and trace; WAHA docs warn against debug and trace in production because they generate excessive logs.",
      "secret": false,
      "strategy": "default",
      "default": "info"
    },
    {
      "key": "WAHA_LOG_FORMAT",
      "service": "WAHA Secure with Webhook",
      "description": "Controls log output format. PRETTY is the default and is easier locally, while JSON is better for centralized log processing.",
      "secret": false,
      "strategy": "default",
      "default": "JSON"
    },
    {
      "key": "WAHA_HOOK_EVENTS",
      "service": "WAHA Secure with Webhook",
      "description": "Comma-separated list of webhook events to send. message subscribes only to message events; WAHA docs warn that subscribing to * or all events can generate a large number of requests in production.",
      "secret": false,
      "strategy": "default",
      "default": "message"
    },
    {
      "key": "WAHA_MEDIA_STORAGE",
      "service": "WAHA Secure with Webhook",
      "description": "Selects where incoming media files are stored. WAHA supports local file storage, S3 storage, and PostgreSQL-backed media storage.",
      "secret": false,
      "strategy": "default",
      "default": "LOCAL"
    },
    {
      "key": "WHATSAPP_FILES_FOLDER",
      "service": "WAHA Secure with Webhook",
      "description": "Local directory where downloaded WhatsApp media files are stored. Persist this path on a volume if you want files to survive restarts and redeploys.",
      "secret": false,
      "strategy": "default",
      "default": "/data/.media"
    },
    {
      "key": "WAHA_DASHBOARD_ENABLED",
      "service": "WAHA Secure with Webhook",
      "description": "Enables or disables the built-in WAHA dashboard login UI. This is separate from API-key auth.",
      "secret": false,
      "strategy": "default",
      "default": "True"
    },
    {
      "key": "WHATSAPP_START_SESSION",
      "service": "WAHA Secure with Webhook",
      "description": "Session name, or comma-separated session names, that WAHA should auto-start on launch.",
      "secret": false,
      "strategy": "default",
      "default": "default"
    },
    {
      "key": "WAHA_DASHBOARD_PASSWORD",
      "service": "WAHA Secure with Webhook",
      "description": "Password for the WAHA dashboard login. Use a generated value instead of example/default credentials.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "WAHA_DASHBOARD_USERNAME",
      "service": "WAHA Secure with Webhook",
      "description": "Username for the WAHA dashboard login. Use a generated value instead of example/default credentials.",
      "secret": false,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "WHATSAPP_DEFAULT_ENGINE",
      "service": "WAHA Secure with Webhook",
      "description": "Default WhatsApp engine for sessions. Supported values are WEBJS, NOWEB, and GOWS; the documented default is WEBJS.",
      "secret": false,
      "strategy": "default",
      "default": "WEBJS"
    },
    {
      "key": "WHATSAPP_FILES_LIFETIME",
      "service": "WAHA Secure with Webhook",
      "description": "Number of seconds media files are kept before cleanup. Set it to 0 to disable automatic deletion.",
      "secret": false,
      "strategy": "default",
      "default": "0"
    },
    {
      "key": "WHATSAPP_SWAGGER_ENABLED",
      "service": "WAHA Secure with Webhook",
      "description": "Enables or disables the built-in Swagger UI. This protects the docs panel only and does not replace API-key auth.",
      "secret": false,
      "strategy": "default",
      "default": "True"
    },
    {
      "key": "WAHA_LOCAL_STORE_BASE_DIR",
      "service": "WAHA Secure with Webhook",
      "description": "Base directory for local WAHA session storage. This is where session state is kept when using local storage, and persistent storage is required if you want sessions to survive redeploys without rescanning QR codes.",
      "secret": false,
      "strategy": "default",
      "default": "/data/.sessions"
    },
    {
      "key": "WAHA_RESTART_ALL_SESSIONS",
      "service": "WAHA Secure with Webhook",
      "description": "Restarts saved/stopped sessions after container restart. WAHA’s docs describe this behavior under WHATSAPP_RESTART_ALL_SESSIONS; if your image supports the WAHA_ alias, the meaning is the same.",
      "secret": false,
      "strategy": "default",
      "default": "True"
    },
    {
      "key": "WHATSAPP_SWAGGER_PASSWORD",
      "service": "WAHA Secure with Webhook",
      "description": "Password for Swagger UI login. Use a generated value instead of example/default credentials.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "WHATSAPP_SWAGGER_USERNAME",
      "service": "WAHA Secure with Webhook",
      "description": "Username for Swagger UI login. Use a generated value instead of example/default credentials.",
      "secret": false,
      "strategy": "generate",
      "generate": "random_base64_32"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "waha-secure-with-webhook"
      }
    },
    "cli": "railway deploy --template waha-secure-with-webhook",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "574011c7-1e22-428f-9eba-016809ea297b",
            "serializedConfig": {
              "services": {
                "ed1811c4-732a-44f7-a5e5-689f035f4787": {
                  "name": "WAHA Secure with Webhook",
                  "source": {
                    "image": "devlikeapro/waha:latest"
                  },
                  "variables": {
                    "WAHA_API_KEY": {
                      "isOptional": false,
                      "description": "API key used to secure WAHA’s REST API. Clients must send it in the X-Api-Key header. WAHA accepts either a plain secret or a sha512:-prefixed hash, and the hash form is the recommended production setup.",
                      "defaultValue": "{{WAHA_API_KEY}}"
                    },
                    "WAHA_BASE_URL": {
                      "isOptional": false,
                      "description": "Base URL used to build the media.url field in webhook events. ",
                      "defaultValue": "http://${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "WAHA_HOOK_URL": {
                      "isOptional": true,
                      "description": "Webhook destination WAHA posts events to. The official docs document this setting as WHATSAPP_HOOK_URL; it defines where subscribed webhook events are delivered.",
                      "defaultValue": "http://backend:8080/webhook"
                    },
                    "WAHA_PRINT_QR": {
                      "isOptional": false,
                      "description": "Controls whether login QR codes are printed into the service logs. Set it to False to keep Railway logs cleaner.",
                      "defaultValue": "False"
                    },
                    "WAHA_LOG_LEVEL": {
                      "description": "Controls log verbosity. Supported levels are error, warn, info, debug, and trace; WAHA docs warn against debug and trace in production because they generate excessive logs.",
                      "defaultValue": "info"
                    },
                    "WAHA_LOG_FORMAT": {
                      "isOptional": false,
                      "description": "Controls log output format. PRETTY is the default and is easier locally, while JSON is better for centralized log processing.",
                      "defaultValue": "JSON"
                    },
                    "WAHA_HOOK_EVENTS": {
                      "isOptional": true,
                      "description": "Comma-separated list of webhook events to send. message subscribes only to message events; WAHA docs warn that subscribing to * or all events can generate a large number of requests in production.",
                      "defaultValue": "message"
                    },
                    "WAHA_MEDIA_STORAGE": {
                      "isOptional": false,
                      "description": "Selects where incoming media files are stored. WAHA supports local file storage, S3 storage, and PostgreSQL-backed media storage.",
                      "defaultValue": "LOCAL"
                    },
                    "WHATSAPP_FILES_FOLDER": {
                      "isOptional": false,
                      "description": "Local directory where downloaded WhatsApp media files are stored. Persist this path on a volume if you want files to survive restarts and redeploys.",
                      "defaultValue": "/data/.media"
                    },
                    "WAHA_DASHBOARD_ENABLED": {
                      "isOptional": false,
                      "description": "Enables or disables the built-in WAHA dashboard login UI. This is separate from API-key auth.",
                      "defaultValue": "True"
                    },
                    "WHATSAPP_START_SESSION": {
                      "isOptional": false,
                      "description": "Session name, or comma-separated session names, that WAHA should auto-start on launch.",
                      "defaultValue": "default"
                    },
                    "WAHA_DASHBOARD_PASSWORD": {
                      "isOptional": false,
                      "description": "Password for the WAHA dashboard login. Use a generated value instead of example/default credentials.",
                      "defaultValue": "{{WAHA_DASHBOARD_PASSWORD}}"
                    },
                    "WAHA_DASHBOARD_USERNAME": {
                      "isOptional": false,
                      "description": "Username for the WAHA dashboard login. Use a generated value instead of example/default credentials.",
                      "defaultValue": "{{WAHA_DASHBOARD_USERNAME}}"
                    },
                    "WHATSAPP_DEFAULT_ENGINE": {
                      "isOptional": false,
                      "description": "Default WhatsApp engine for sessions. Supported values are WEBJS, NOWEB, and GOWS; the documented default is WEBJS.",
                      "defaultValue": "WEBJS"
                    },
                    "WHATSAPP_FILES_LIFETIME": {
                      "isOptional": false,
                      "description": "Number of seconds media files are kept before cleanup. Set it to 0 to disable automatic deletion.",
                      "defaultValue": "0"
                    },
                    "WHATSAPP_SWAGGER_ENABLED": {
                      "isOptional": false,
                      "description": "Enables or disables the built-in Swagger UI. This protects the docs panel only and does not replace API-key auth.",
                      "defaultValue": "True"
                    },
                    "WAHA_LOCAL_STORE_BASE_DIR": {
                      "isOptional": false,
                      "description": "Base directory for local WAHA session storage. This is where session state is kept when using local storage, and persistent storage is required if you want sessions to survive redeploys without rescanning QR codes.",
                      "defaultValue": "/data/.sessions"
                    },
                    "WAHA_RESTART_ALL_SESSIONS": {
                      "isOptional": false,
                      "description": "Restarts saved/stopped sessions after container restart. WAHA’s docs describe this behavior under WHATSAPP_RESTART_ALL_SESSIONS; if your image supports the WAHA_ alias, the meaning is the same.",
                      "defaultValue": "True"
                    },
                    "WHATSAPP_SWAGGER_PASSWORD": {
                      "isOptional": false,
                      "description": "Password for Swagger UI login. Use a generated value instead of example/default credentials.",
                      "defaultValue": "{{WHATSAPP_SWAGGER_PASSWORD}}"
                    },
                    "WHATSAPP_SWAGGER_USERNAME": {
                      "isOptional": false,
                      "description": "Username for Swagger UI login. Use a generated value instead of example/default credentials.",
                      "defaultValue": "{{WHATSAPP_SWAGGER_USERNAME}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:8080": {
                        "port": 8080
                      }
                    }
                  },
                  "volumeMounts": {
                    "ed1811c4-732a-44f7-a5e5-689f035f4787": {
                      "mountPath": "/data"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {},
  "resources": {
    "expected_services": 1,
    "needs_volume": true
  },
  "generated_at": "2026-09-20T10:14:37.339Z",
  "generator_version": "0.1.0",
  "status": "validated",
  "validated_at": "2026-09-18T09:58:54.194Z",
  "success_rate_30d": 1,
  "validation": {
    "last_run_id": "run_8a0137963ff64773a2bd",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": true
      },
      {
        "name": "stays_up",
        "passed": true
      }
    ],
    "typical_ready_seconds": 53,
    "typical_build_seconds": 0,
    "typical_start_seconds": 10,
    "slowest_service": "WAHA Secure with Webhook"
  }
}
