soga-v1 webapi Developer Documentation
Introduction
The soga-v1 panel type is a set of custom webapi interfaces defined by soga v2.12.3+. You can implement them in your own panel by following the API documentation below, then set type=soga-v1 in the soga configuration to use this webapi
webapi_url Configuration
You can customize your webapi_url path. The soga license code will be bound to this full webapi_url path, and when soga calls the webapi it automatically joins the webapi_url path with the endpoint uri, e.g. https://www.website.com/your/custom/uri/api/v1/node
webapi_url=https://www.website.com/your/custom/uri/API
All endpoints exchange data in
jsonformat
Every request includes the following
request headers
| Key | Description |
|---|---|
| API-KEY | webapi_key from the soga configuration, used by the panel to authenticate webapi requests |
| NODE-ID | Node id |
| NODE-TYPE | Node type: vmess vless shadowsocks shadowsocksr trojan hysteria anytls mieru |
| IF-NONE-MATCH | Applies to GET endpoints. If the webapi response headers contain ETAG data, the next request will include this header to reduce webapi traffic. The panel must implement ETAG correctly |
WARNING
The following endpoints are required. If any of them returns 404, soga will not work properly
Get Node Info GET <webapi_url>/api/v1/node
Response
The response differs by node type; return the data format that matches the node type
vmess node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"stream_type": "ws", // options: tcp ws http h2 grpc
"tls_type": "none", // options: none tls
"ech_key": "", // v2.17.1+, ECH private key, applies when tls is used, leave empty to disable, can be generated with sing-box generate ech-keypair
"path": "/path", // required for ws
"service_name": "service_name" // required for grpc
}
}trojan node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"stream_type": "ws", // options: tcp ws http h2 grpc
"ech_key": "", // v2.17.1+, ECH private key, applies when tls is used, leave empty to disable, can be generated with sing-box generate ech-keypair
"path": "/path", // required for ws
"service_name": "service_name" // required for grpc
}
}ss node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"cipher": "aes-128-gcm", // see the ciphers supported by soga ss
"password": "", // node password required when the cipher is ss2022, base64 encoded
"obfs": "plain", // options: plain simple_obfs_http simple_obfs_tls
"path": "/path", // optional for simple_obfs_http obfuscation
"host": "www.server.com" // optional for simple_obfs_http and simple_obfs_tls obfuscation
}
}ssr node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"method": "chacha20-ietf", // see the ciphers supported by soga ssr
"password": "asd", // password
"protocol": "auth_chain_a", // see the protocols supported by soga ssr
"obfs": "http_simple", // see the obfuscation methods supported by soga ssr
"single_port_type": "protocol" // options: protocol obfs, meaning protocol single port and obfs single port respectively
}
}vless node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"stream_type": "tcp", // options: tcp ws http h2 grpc xhttp
"tls_type": "reality", // options: none tls reality
"ech_key": "", // v2.17.1+, ECH private key, applies when tls is used, leave empty to disable, can be generated with sing-box generate ech-keypair
// reality settings
"flow": "xtls-rprx-vision",
"server_names": ["www.server1.com", "www.server2.com"],
"private_key": "",
"short_ids": ["1234567890123456", "1234567890123456"],
"dest": "www.server.com:443",
// v2.13.7+, empty or "none" disables vless encryption, any other value is used as the vless decryption parameter
"decryption": "",
"path": "/path", // required for ws
"service_name": "service_name", // required for grpc
"xhttp_settings": { // xhttp settings, see: https://github.com/XTLS/Xray-core/discussions/4113
"host": "example.com",
"path": "/yourpath",
"mode": "auto",
"extra": {
"headers": {
// "key": "value"
},
"xPaddingBytes": "100-1000",
"noSSEHeader": false,
"scMaxEachPostBytes": 1000000,
"scMaxBufferedPosts": 30,
"scStreamUpServerSecs": "20-80"
}
}
}
}hysteria node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"obfs": "salamander", // options: plain salamander
"obfs_password": "", // obfuscation password
"ech_key": "", // v2.17.1+, ECH private key, applies when tls is used, leave empty to disable, can be generated with sing-box generate ech-keypair
"up_mbps": 1000, // upload bandwidth, in Mbps, bbr is used if both upload and download bandwidth are 0
"down_mbps": 1000 // download bandwidth, in Mbps, bbr is used if both upload and download bandwidth are 0
}
}anytls node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"tls_type": "tls", // options: none tls reality
"ech_key": "", // v2.17.1+, ECH private key, applies when tls is used, leave empty to disable, can be generated with sing-box generate ech-keypair
// reality settings
"flow": "xtls-rprx-vision",
"server_names": ["www.server1.com", "www.server2.com"],
"private_key": "",
"short_ids": ["1234567890123456", "1234567890123456"],
"dest": "www.server.com:443",
"padding_scheme": [ // paddingScheme, leave empty to use the default
"stop=8",
"0=30-30",
"1=100-400",
"2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
"3=9-9,500-1000",
"4=500-1000",
"5=500-1000",
"6=500-1000",
"7=500-1000"
]
}
}mieru node type
{
"basic": { // optional
"pull_interval": 60, // optional, interval for pulling data, in seconds
"push_interval": 60, // optional, interval for pushing data, in seconds
"speed_limit": 0 // optional, total speed limit for the node, in Mbps, 0 means unlimited
},
"config": {
"port": 12345, // listening port
"transport": "TCP" // transport protocol, only TCP is supported for now
}
}Get Users GET <webapi_url>/api/v1/users
Response
The response differs by node type; return the data format that matches the node type
vmess vless node types
[
{
"id": 1,
"uuid": "701534e1-8540-49f3-87af-71680a1b97ff",
"speed_limit": 0, // user speed limit, in Mbps, 0 means unlimited
"device_limit": 0, // user IP limit, 0 means unlimited
"tcp_limit": 0 // user tcp connection limit, 0 means unlimited
},
{
"id": 2,
"uuid": "247862fd-1490-447d-8cec-971f756f1424",
"speed_limit": 0,
"device_limit": 0,
"tcp_limit": 0
}
]trojan ss hysteria ssr anytls node types
[
{
"id": 1,
"password": "password1",
"speed_limit": 0, // user speed limit, in Mbps, 0 means unlimited
"device_limit": 0, // user IP limit, 0 means unlimited
"tcp_limit": 0 // user tcp connection limit, 0 means unlimited
},
{
"id": 2,
"password": "password2",
"speed_limit": 0,
"device_limit": 0,
"tcp_limit": 0
}
]mieru node type
[
{
"id": 1,
"username": "username1", // mieru username
"password": "password1", // mieru password
"speed_limit": 0, // user speed limit, in Mbps, 0 means unlimited
"device_limit": 0, // user IP limit, 0 means unlimited
"tcp_limit": 0 // user tcp connection limit, 0 means unlimited
},
{
"id": 2,
"username": "username2",
"password": "password2",
"speed_limit": 0,
"device_limit": 0,
"tcp_limit": 0
}
]Get Audit Rules GET <webapi_url>/api/v1/audit_rules
Each string is one audit rule; see the soga documentation for the exact format
Response
[
{
"id": 1, // audit rule id, used when reporting user audit events
"rule": "google" // audit rule
},
{
"id": 2,
"rule": "regexp:.*google\.com"
}
]Get Audit Whitelist GET <webapi_url>/api/v1/white_list
See the whitelist rules in the soga documentation for details
The audit whitelist returned by this endpoint is automatically merged with the local whiteList file
Response
[
"google",
"regexp:.*google\.com",
"domain:google.com",
"full:google.com",
"geosite:google",
"ip:192.168.0.0/16",
"geoip:cn",
"port:1-1024,12345,23456"
]Report User Traffic POST <webapi_url>/api/v1/traffic
Request Body
[
{
"id": 1, // user id
"u": 1024, // upload traffic, in bytes
"d": 1024 // download traffic, in bytes
},
{
"id": 2, // user id
"u": 1024, // upload traffic, in bytes
"d": 1024 // download traffic, in bytes
}
]Response
{
"code": 0, // 0 means success, any other value means failure
"message": "" // custom error message
}Report User Online IPs POST <webapi_url>/api/v1/alive_ip
Request Body
[
{
"id": 1,
"ips": ["1.2.3.4", "2.3.4.5"]
},
{
"id": 2,
"ips": ["3.4.5.6"]
}
]Response
{
"code": 0, // 0 means success, any other value means failure
"message": "" // custom error message
}Report User Audit Events POST <webapi_url>/api/v1/audit_log
If the same user triggers the same audit rule multiple times, it is recorded only once
Request Body
[
{
"user_id": 1, // user id
"audit_id": 2 // id of the triggered audit rule
},
{
"user_id": 1,
"audit_id": 3
},
{
"user_id": 2,
"audit_id": 2
}
]Response
{
"code": 0, // 0 means success, any other value means failure
"message": "" // custom error message
}Report Node Status POST <webapi_url>/api/v1/status
Request Body
{
"cpu": 23.5, // average CPU usage since the last report
"mem": {
"total": 1073741824, // total memory, in bytes
"used": 536870912 // memory used, in bytes
},
"swap": {
"total": 1073741824, // total swap, in bytes
"used": 536870912 // swap used, in bytes
},
"disk": {
"total": 1073741824, // total disk space, in bytes
"used": 536870912 // disk space used, in bytes
},
"uptime": 123456 // system uptime, in seconds
}Response
{
"code": 0, // 0 means success, any other value means failure
"message": "" // custom error message
}