curl --request POST \
--url https://api.range.org/v1/risk/alert-rules/pack \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"pack_type": "squads",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"rules": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "High gas on eth",
"severity": "high",
"parameters": {}
}
],
"pack_label": "Treasury multisig",
"override": false
}
'import requests
url = "https://api.range.org/v1/risk/alert-rules/pack"
payload = {
"pack_type": "squads",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"rules": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "High gas on eth",
"severity": "high",
"parameters": {}
}
],
"pack_label": "Treasury multisig",
"override": False
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
pack_type: 'squads',
pack_address: 'Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS',
rules: [
{
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'High gas on eth',
severity: 'high',
parameters: {}
}
],
pack_label: 'Treasury multisig',
override: false
})
};
fetch('https://api.range.org/v1/risk/alert-rules/pack', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v1/risk/alert-rules/pack",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'pack_type' => 'squads',
'pack_address' => 'Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS',
'rules' => [
[
'id' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'name' => 'High gas on eth',
'severity' => 'high',
'parameters' => [
]
]
],
'pack_label' => 'Treasury multisig',
'override' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v1/risk/alert-rules/pack"
payload := strings.NewReader("{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.range.org/v1/risk/alert-rules/pack")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v1/risk/alert-rules/pack")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}"
response = http.request(request)
puts response.read_body{
"pack_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"items": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"workspace_id": "workspace-123",
"rule_type": "GasPressure",
"severity": "high",
"parameters": {
"threshold": 90
},
"trigger": "BLOCK",
"enabled": true,
"version": 1,
"subscribed_channels": [
{
"alert_channel_id": "44444444-4444-4444-4444-444444444445",
"min_severity": null
}
],
"created_at": "2026-05-14T12:00:00.000Z",
"updated_at": "2026-05-14T12:00:00.000Z",
"name": "High gas on eth",
"network": "eth",
"runner_id": "alert-runner-eth-v2",
"pack_type": "squads",
"pack_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"pack_label": "Treasury multisig",
"alert_template": {
"id": "1",
"type": "large_transfer",
"label": "Large Transfer",
"description": "A large transfer was detected on {{network}}",
"network": "eth",
"severity": "high",
"tags": [
"defi",
"transfer"
],
"trigger": "BLOCK",
"parameters": [
{
"label": "Wallet",
"description": "The address to monitor",
"field": "address",
"field_type": "Address",
"optional": false
}
],
"packs": [
{
"type": "squads",
"required": true
}
]
}
}
]
}{
"warning": "An alert pack already covers this address.",
"existing_pack_ids": [
"<string>"
]
}Create a multisig alert rule pack
Creates every member rule of one multisig pack atomically and mints a shared pack_id. Every referenced template must have the requested pack_type enabled; member rules may span networks and runners. If an existing pack already covers the same address, the request is rejected with a 409 soft-warn; re-submit with override: true to create anyway. Member rules stay individually editable afterwards via PATCH.
curl --request POST \
--url https://api.range.org/v1/risk/alert-rules/pack \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"pack_type": "squads",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"rules": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "High gas on eth",
"severity": "high",
"parameters": {}
}
],
"pack_label": "Treasury multisig",
"override": false
}
'import requests
url = "https://api.range.org/v1/risk/alert-rules/pack"
payload = {
"pack_type": "squads",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"rules": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "High gas on eth",
"severity": "high",
"parameters": {}
}
],
"pack_label": "Treasury multisig",
"override": False
}
headers = {
"X-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
pack_type: 'squads',
pack_address: 'Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS',
rules: [
{
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
name: 'High gas on eth',
severity: 'high',
parameters: {}
}
],
pack_label: 'Treasury multisig',
override: false
})
};
fetch('https://api.range.org/v1/risk/alert-rules/pack', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.range.org/v1/risk/alert-rules/pack",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'pack_type' => 'squads',
'pack_address' => 'Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS',
'rules' => [
[
'id' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'name' => 'High gas on eth',
'severity' => 'high',
'parameters' => [
]
]
],
'pack_label' => 'Treasury multisig',
'override' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.range.org/v1/risk/alert-rules/pack"
payload := strings.NewReader("{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.range.org/v1/risk/alert-rules/pack")
.header("X-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v1/risk/alert-rules/pack")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"pack_type\": \"squads\",\n \"pack_address\": \"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS\",\n \"rules\": [\n {\n \"id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"name\": \"High gas on eth\",\n \"severity\": \"high\",\n \"parameters\": {}\n }\n ],\n \"pack_label\": \"Treasury multisig\",\n \"override\": false\n}"
response = http.request(request)
puts response.read_body{
"pack_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"items": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"workspace_id": "workspace-123",
"rule_type": "GasPressure",
"severity": "high",
"parameters": {
"threshold": 90
},
"trigger": "BLOCK",
"enabled": true,
"version": 1,
"subscribed_channels": [
{
"alert_channel_id": "44444444-4444-4444-4444-444444444445",
"min_severity": null
}
],
"created_at": "2026-05-14T12:00:00.000Z",
"updated_at": "2026-05-14T12:00:00.000Z",
"name": "High gas on eth",
"network": "eth",
"runner_id": "alert-runner-eth-v2",
"pack_type": "squads",
"pack_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"pack_address": "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS",
"pack_label": "Treasury multisig",
"alert_template": {
"id": "1",
"type": "large_transfer",
"label": "Large Transfer",
"description": "A large transfer was detected on {{network}}",
"network": "eth",
"severity": "high",
"tags": [
"defi",
"transfer"
],
"trigger": "BLOCK",
"parameters": [
{
"label": "Wallet",
"description": "The address to monitor",
"field": "address",
"field_type": "Address",
"optional": false
}
],
"packs": [
{
"type": "squads",
"required": true
}
]
}
}
]
}{
"warning": "An alert pack already covers this address.",
"existing_pack_ids": [
"<string>"
]
}Authorizations
Authorization method required to allow user to access the api endpoints.
Body
The multisig provider this pack monitors (e.g. squads). Every referenced template must have this pack type enabled.
64"squads"
The multisig address every member rule of this pack covers.
128"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
The member rules to create. Every entry must reference a template with this pack type enabled.
1Show child attributes
Show child attributes
Display label for grouping the pack in rule lists.
255"Treasury multisig"
Set true to create the pack even though an existing pack already covers the same address (skips the 409 soft-warn).
false
Was this page helpful?