Skip to main content

Response Rules

warning

If you are unsure about the changes you are making, please proceed with caution. Incorrect modifications can disrupt the system.

Response Rules (SRR) are an ordered (top-to-bottom; if the rule applies, the evaluation stops), JSON set of rules that the backend evaluates for incoming subscription requests.

Templates menu
tip

Response Rules will override the External Squads configuration.

Create a Custom Response Rule​

Let's create a custom Response Rule that will give Android user with Happ client app a custom Template, and a custom header.

It should look something like this:

  1. The user requests a subscription
  2. Remnawave recognizes that he's using Happ on Android.
  3. Remnawave responds with a custom Happ Android Template and adds a custom header HappTheBestAppOnTheWorld.

Here's how the rule could look:

{
"name": "Happ Android",
"description": "Serve custom JSON for Android",
"enabled": true,
"operator": "AND", // Both "user-agent" and "x-device-os" must be matched
"conditions": [
{
"caseSensitive": false,
"headerName": "user-agent",
"operator": "CONTAINS",
"value": "happ"
},
{
"caseSensitive": false,
"headerName": "x-device-os",
"operator": "EQUALS",
"value": "android"
}
],
"responseType": "XRAY_JSON",
"responseModifications": {
"subscriptionTemplate": "Happ Android", // Serve the custom Template
"headers": [ // Serve the custom headers
{
"key": "x-provider-id",
"value": "HappTheBestAppOnTheWorld"
}
]
}
}

rules​

Each rule is an object with the following fields:

  • name (string) β€” required; 1..50 chars

    "name": "Block Legacy Clients"
  • description (string) β€” optional; max 250 chars

    "description": "Blocks requests from legacy clients"
  • enabled (boolean) β€” required
    Controls whether the rule is active. When false, the rule is skipped during evaluation.

    "enabled": true
  • operator (enum) β€” required; AND or OR

    "operator": "AND" // Rule matches only if ALL conditions match
    "operator": "OR" // Rule matches if ANY condition matches
  • conditions (array)
    List of conditions to evaluate.

    "conditions": []  // Empty = match everything (use for fallback rules)
  • responseType (enum) β€” required
    Determines what response to send when the rule matches:

    TypeDescription
    MIHOMOMihomo YAML config
    CLASHClash YAML config
    STASHStash YAML config
    SINGBOXSing-box JSON config
    XRAY_JSONXray JSON config
    XRAY_BASE64Base64-encoded Xray config
    BROWSERHTML page for browsers
    BLOCKHTTP 403 Forbidden
    STATUS_CODE_404HTTP 404 Not Found
    STATUS_CODE_451HTTP 451 Unavailable For Legal Reasons
    SOCKET_DROPDrop the socket connection
  • responseModifications (array) - optional
    Additional modifications to apply to the response. Can be used to give a custom Template or headers.

    • subscriptionTemplate (string) - optional
      Define a specific Template to be given if the rule is matched.
    • headers (array) - optional
      Respond with a custom header.
      • key (string) - optional
        Header name.
      • value (string) - optional
        Header value.
    • applyHeadersToEnd (boolean) - optional
      By default, headers are added when forming the response. In some cases, headers set in SRR may be overridden by headers from other parts of the system (such as External Squads). If you set this flag to true, headers from SRR will be added at the very end, just before the response is sent. In this case, SRR headers may override headers from other sections.
    • ignoreHostXrayJsonTemplate (boolean) - optional
      Each Host may have its own Xray Json Template. If you set this flag to true, the Xray Json Template defined by the SRR will be used. The Host's Xray Json Template will be ignored.
    • ignoreServeJsonAtBaseSubscription (boolean) - optional
      In certain scenarios you might want to serve XRAY_BASE64 to client apps that are recognized by the Panel as capable of accepting XRAY_JSON when Serve JSON at Base Subscription is enabled.
      If you set this flag to true, the Serve JSON at Base Subscription setting will be ignored (set to false).
    "responseType": "SINGBOX",
    "responseModifications": {
    "applyHeadersToEnd": true,
    "headers": [
    {
    "key": "X-Custom-Header",
    "value": "CustomValue"
    }
    ],
    "ignoreHostXrayJsonTemplate": true,
    "ignoreServeJsonAtBaseSubscription": true,
    "subscriptionTemplate": "Singbox Legacy"
    }

rules.conditions​

  • headerName (string) β€” required
    The HTTP header to check. Must comply with RFC 7230.

    "headerName": "user-agent"    // Client app user-agent
  • operator (enum) β€” required
    Comparison operation to perform:

    OperatorDescription
    EQUALSExact match
    NOT_EQUALSInverse exact match
    CONTAINSSubstring exists
    NOT_CONTAINSSubstring absent
    STARTS_WITHPrefix match
    NOT_STARTS_WITHPrefix absence
    ENDS_WITHSuffix match
    NOT_ENDS_WITHSuffix absence
    REGEXRegular expression
    NOT_REGEXInverse regex
  • value (string) β€” required; 1..255 chars
    The value to compare against the header value.

    "value": "^sfa|sfi|sfm|sft|karing|singbox|rabbithole"
  • caseSensitive (boolean) β€” required

    "caseSensitive": true   // The value is compared as is
    "caseSensitive": false // The value is lowercased before comparison
Serve OS-specific Templates

You can easily respond with different Templates to different OSes.

In the example below users with iOS will get a Happ iOS JSON, and users with Android will get a Happ Android JSON.

{
"name": "Happ Android",
"description": "Serve custom JSON for Android",
"enabled": true,
"operator": "AND",
"conditions": [
{
"caseSensitive": false,
"headerName": "user-agent",
"operator": "CONTAINS",
"value": "happ"
},
{
"caseSensitive": false,
"headerName": "x-device-os",
"operator": "CONTAINS",
"value": "android"
}
],
"responseType": "XRAY_JSON",
"responseModifications": {
"subscriptionTemplate": "Happ Android"
}
},
{
"name": "Happ iOS",
"description": "Serve custom JSON for iOS",
"enabled": true,
"operator": "AND",
"conditions": [
{
"caseSensitive": false,
"headerName": "user-agent",
"operator": "CONTAINS",
"value": "happ"
},
{
"caseSensitive": false,
"headerName": "x-device-os",
"operator": "CONTAINS",
"value": "ios"
}
],
"responseType": "XRAY_JSON",
"responseModifications": {
"subscriptionTemplate": "Happ iOS"
}
}
Header Resolution Rules
  1. Header names are case-insensitive
    "user-agent" === "User-Agent" === "USER-AGENT"
  2. If a header has multiple values, these will be concatenated into a single string, separated by commas.
  3. Missing value of the headers result in skipped rule.