SoloIP API

API reference

Authentication, data objects, endpoint reference, and examples for scripts, operations platforms, and automation.

API base path/soloip/api/v1
AccessAPI access must be enabled

Manage nodes, routing rules, and proxy services

All endpoint paths use /soloip/api/v1 . Confirm that SoloIP is activated and configure an API token in the management UI before calling the API.

1. Basic information

All endpoints use this base path:

/soloip/api/v1

Request headers:

Authorization: Bearer <API_TOKEN>
Content-Type: application/json
  • Find or reset API_TOKEN in the SoloIP API settings page.
  • Business endpoints accept JSON request bodies unless an endpoint says otherwise.
  • HTTP 200 means the request was handled; inspect msg, data, or error for the business result.
  • An endpoint that is not exposed to the public API returns 403 API_ENDPOINT_NOT_ALLOWED.

Common errors:

HTTP statusErrorMeaning
401API Token invalidThe token is missing, malformed, or does not match the device
403API_ACCESS_REQUIREDAPI access is not enabled for the license
403API_TRIAL_QUOTA_EXHAUSTEDThe API trial quota is exhausted
403API_ENDPOINT_NOT_ALLOWEDThis token cannot call the endpoint
400Error textRequest parameters are invalid
500Error textServer-side execution failed
Back to section index

2. Common objects and conventions

2.1 Node

{
  "id": 1,
  "name": "HK-01",
  "protocol": "socks5",
  "config_json": "{\"server\":\"1.2.3.4\",\"port\":1080}",
  "group": "hong-kong",
  "created_at": "2026-05-18T10:00:00Z"
}

config_json is a protocol-specific JSON string. External tools should use the batch endpoint for stable field updates instead of relying on internal protocol fields.

2.2 VPNLine (L2TP/PPTP)

{
  "id": 1,
  "type": "l2tp",
  "name": "l2tp_1",
  "server": "vpn.example.com",
  "port": 1701,
  "username": "user",
  "password": "pass",
  "secret": "ipsec-secret",
  "interface": "auto",
  "comment": "primary line",
  "dns_profile": "auto",
  "dns_servers": [],
  "is_enabled": true,
  "is_online": true
}

type is l2tp or pptp; is_enabled is the configured switch and is_online means that the system interface currently has an IPv4 address. dns_profile accepts auto, domestic, outbound, return, or custom; custom requires dns_servers.

2.3 Rule

{
  "id": 1,
  "ip": "192.168.50.100",
  "mac": "AA:BB:CC:DD:EE:FF",
  "comment": "test device",
  "is_enabled": true,
  "target_node": "HK-01",
  "upload_limit_kbps": 5120,
  "download_limit_kbps": 20480,
  "created_at": "2026-05-18T10:00:00Z",
  "updated_at": "2026-05-18T10:00:00Z"
}

Stable target_node forms:

FormExample
Node nameHK-01
Node groupGroup_hong-kong
Interface or lineInterface:wan1, Interface:l2tp_1, Interface:pptp_1
Direct or rejectDIRECT, REJECT

Use the explicit Group_ and Interface: prefixes. Interface: is for routing rules, not proxy-service outbound values.

2.4 ProxyService

{
  "id": 1,
  "name": "wan1-http",
  "outbound_interface": "wan1",
  "port": 20001,
  "username": "user",
  "password": "pass",
  "is_enabled": true,
  "created_at": "2026-05-18T10:00:00Z"
}

outbound_interface uses a bare interface name. The listener port must not conflict with a system-reserved port.

Back to section index

3. System queries

GET /system/status

Returns service state, uptime, version, API access, connections, and memory.

curl -H "Authorization: Bearer soloip_xxx" \
  http://192.168.50.1/soloip/api/v1/system/status

Possible status values include running, stopped, and restoring. Automation should primarily use status, hasAPIAccess, connections, and memory.

GET /system/traffic

Returns current connections and memory. up and down are reserved fields and commonly return 0.

{ "up": 0, "down": 0, "connections": 42, "memory": 15728640 }

GET /system/interfaces

Returns interfaces that can be used as node outbound paths, including enabled L2TP/PPTP line names.

{ "interfaces": ["wan1", "wan2", "pppoe_0", "l2tp_1", "pptp_1"] }

GET /system/interfaces-with-ip

Returns interface names and current IPv4 addresses, useful before creating a proxy service.

{
  "interfaces": [
    { "name": "wan1", "ip": "100.64.1.2" },
    { "name": "l2tp_1", "ip": "10.0.0.2" },
    { "name": "pptp_1", "ip": "" }
  ]
}
Back to section index

4. Node management

Endpoint overview

MethodPathPurpose
GET/nodesList nodes
POST/nodesAdd a node
PUT/nodes/{id}Edit a node
DELETE/nodes/{id}Delete a node
DELETE/nodes/batchDelete nodes in bulk
PATCH/nodes/batchChange group, egress, or dedicated DNS
POST/nodes/importImport nodes in bulk
GET/nodes/delayCheck one node
GET/nodes/delay/allCheck every node

GET /nodes

Returns { "data": [Node, ...] }.

POST /nodes

{
  "name": "HK-01",
  "protocol": "socks5",
  "config_json": "{\"server\":\"1.2.3.4\",\"port\":1080}",
  "group": "hong-kong"
}

Response: { "msg": "node added", "id": 1 }.

PUT /nodes/{id}

Send the complete editable node object. The response is { "msg": "node updated", "id": 1 }.

DELETE /nodes/{id}

Response: { "msg": "node deleted", "id": 1 }.

DELETE /nodes/batch

{ "ids": [1, 2, 3] }

PATCH /nodes/batch

Changes group, outbound interface, relay, or dedicated DNS for selected IDs.

{
  "ids": [1, 2],
  "group": "hong-kong",
  "interface_name": "wan1",
  "dialer_proxy": "",
  "node_dns_profile": "custom",
  "node_dns_servers": "1.1.1.1,8.8.8.8"
}

interface_name and dialer_proxy are mutually exclusive. node_dns_profile=custom requires non-empty node_dns_servers. The response includes the number of updated nodes.

POST /nodes/import

{
  "type": "socks5",
  "text": "1.2.3.4,1080,user,pass,HK-01\n5.6.7.8,1080,user,pass,HK-02",
  "replace": false,
  "group": "hong-kong",
  "autoNodeName": false,
  "autoNodeNameStartIndex": 1
}

Supported formats include socks5 (IP,Port,User,Pass[,Name]), ss (IP,Port,Cipher,Password[,Name]), vlessvmess share fields, and the key/value others format. replace=true clears current nodes first. The response includes imported, skipped, and error counts.

GET /nodes/delay

Use ?name=<node-name> to check one node. The response includes latency and diagnostic information when available.

GET /nodes/delay/all

Checks all nodes and returns the per-node result. Treat a saved node without a successful diagnostic as unavailable for a production rule.

Back to section index

5. L2TP/PPTP line management

Endpoint overview

MethodPathPurpose
GET/vpn-linesList lines
POST/vpn-linesAdd a line
PUT/vpn-lines/{type}/{name}Edit a line
PATCH/vpn-lines/statusEnable or disable lines
DELETE/vpn-linesDelete lines in bulk
POST/vpn-lines/importImport lines in bulk

GET /vpn-lines

Returns VPNLine objects with is_enabled and is_online.

POST /vpn-lines

{
  "type": "l2tp",
  "name": "l2tp_1",
  "server": "vpn.example.com",
  "port": 1701,
  "username": "user",
  "password": "pass",
  "secret": "ipsec-secret",
  "interface": "auto",
  "comment": "primary line",
  "dns_profile": "auto",
  "dns_servers": []
}

type must be l2tp or pptp; names start with l2tp_ or pptp_ and are at most 15 characters. Default ports are 1701 and 1723. New lines are enabled by default.

PUT /vpn-lines/{type}/{name}

Edits a line. The body may contain a new name, but the type cannot change. A custom DNS profile requires dns_servers.

PATCH /vpn-lines/status

{
  "items": [
    { "type": "l2tp", "name": "l2tp_1" },
    { "type": "pptp", "name": "pptp_1" }
  ],
  "is_enabled": false
}

DELETE /vpn-lines

Send an items array with type and name for each line.

POST /vpn-lines/import

L2TP lines use server,port,user,pass,secret,name,comment or the form without port. PPTP uses server,port,user,pass,name,comment or the form without port. The response includes imported, skipped, and errors.

Back to section index

6. Routing-rule management

Endpoint overview

MethodPathPurpose
GET/rulesList rules
POST/rulesAdd a rule
PUT/rules/{id}Edit a rule
PATCH/rules/{id}/statusEnable or disable one rule
DELETE/rules/{id}Delete one rule
DELETE/rules/batchDelete rules in bulk
PATCH/rules/batch/statusEnable or disable rules in bulk
PATCH/rules/batchChange targets or limits
PATCH/rules/batch/limitsChange limits in bulk
POST/rules/importImport rules in bulk

GET /rules

Returns { "data": [Rule, ...] }.

POST /rules

{
  "ip": "192.168.50.100",
  "mac": "AA:BB:CC:DD:EE:FF",
  "comment": "test device",
  "is_enabled": true,
  "target_node": "Group_hong-kong",
  "upload_limit_kbps": 5120,
  "download_limit_kbps": 20480
}

PUT /rules/{id}

Edits the address, comment, target, enabled state, and limits. Use a complete body for predictable automation.

PATCH /rules/{id}/status

{ "is_enabled": false }

DELETE /rules/{id}

Deletes the rule and cleans its firewall entry.

DELETE /rules/batch

{ "ips": ["192.168.50.100", "192.168.50.101"] }

PATCH /rules/batch/status

{ "ips": ["192.168.50.100", "192.168.50.101"], "is_enabled": true }

PATCH /rules/batch

Set at least one update_* field to true.

{
  "ips": ["192.168.50.100", "192.168.50.101"],
  "update_target": true,
  "target_node": "Group_hong-kong",
  "update_upload": true,
  "upload_limit_kbps": 5120,
  "update_download": true,
  "download_limit_kbps": 20480
}

target_node may be a node, Group_<name>, DIRECT, REJECT, or Interface:<ifname>. A limit of 0 means unlimited.

PATCH /rules/batch/limits

Set update_upload and/or update_download with non-negative limit values. At least one update flag must be true.

POST /rules/import

{
  "text": "192.168.50.100,Group_hong-kong,test device\n192.168.50.101,DIRECT,printer\n192.168.50.102,Interface:l2tp_1,vpn path",
  "replace": false
}

Use IP,target,comment. replace=true clears the existing rules before importing.

Back to section index

7. Whitelist management

Endpoint overview

MethodPathPurpose
GET/whitelistRead whitelist settings
PUT/whitelistSave whitelist settings

GET /whitelist

{ "domains": "example.com", "ips": "1.1.1.1,2.2.2.2", "node": "DIRECT" }

PUT /whitelist

Send domains, ips, and node. Domains and IPs accept comma or newline separators. Ordinary domains are matched by hostname. For a non-default port, use scheme://domain:port with http, https, or quic; both the sniffed domain and destination port must match. Use DIRECT, a node name, or Group_<name>; do not add Interface: to a whitelist destination.

Back to section index

8. Proxy-service management

Endpoint overview

MethodPathPurpose
GET/proxy-services/quotaRead proxy-service quota
GET/proxy-servicesList services
POST/proxy-servicesCreate a service
PUT/proxy-services/{id}Edit a service
PATCH/proxy-services/{id}/statusEnable or disable one service
DELETE/proxy-services/{id}Delete one service
DELETE/proxy-services/batchDelete services in bulk
PATCH/proxy-services/batch/statusEnable or disable services in bulk
POST/proxy-services/importImport services in bulk

GET /proxy-services/quota

{ "quota": 10, "used": 1 }

GET /proxy-services

Returns { "data": [ProxyService, ...] }.

POST /proxy-services

{
  "name": "wan1-http",
  "outbound_interface": "wan1",
  "port": 20001,
  "username": "user",
  "password": "pass",
  "is_enabled": true
}

PUT /proxy-services/{id}

Send the editable service fields. The response contains msg and id.

PATCH /proxy-services/{id}/status

{ "is_enabled": false }

DELETE /proxy-services/{id}

Deletes one proxy service.

DELETE /proxy-services/batch

{ "ids": [1, 2, 3] }

PATCH /proxy-services/batch/status

{ "ids": [1, 2, 3], "is_enabled": true }

POST /proxy-services/import

Supported rows are name,outbound_interface,port,username,password, or shorter forms with the name and credentials omitted. Use replace=true only when the complete service list is intentionally being replaced.

Back to section index

9.1 Check status and interfaces

  1. GET /system/status
  2. GET /system/interfaces
  3. GET /system/interfaces-with-ip when an address is required.

9.2 Add a node and route traffic

  1. POST /nodes
  2. GET /nodes/delay?name=<node-name>
  3. POST /rules with a node, group, direct, reject, or interface target.

9.3 Create or manage an L2TP/PPTP line

  1. POST /vpn-lines
  2. GET /vpn-lines and inspect is_enabled and is_online.
  3. PATCH /vpn-lines/status to enable or disable.
  4. PUT /vpn-lines/{type}/{name} to edit.

9.4 Bind a proxy-service egress

  1. GET /proxy-services/quota
  2. GET /system/interfaces-with-ip
  3. POST /proxy-services

9.5 Import in bulk

  1. POST /nodes/import
  2. POST /vpn-lines/import
  3. POST /rules/import
  4. POST /proxy-services/import
Back to section index

10. Compatibility notes

  • Paths in this document omit /soloip/api/v1.
  • Group_ and Interface: are stable rule-target prefixes; include them exactly.
  • Proxy-service outbound_interface is a bare interface name and must not use Interface:.
  • is_online indicates an IPv4 address on the system interface, not detailed dial logs.
  • All create, edit, and batch-update endpoints use JSON request bodies.
  • Example timestamps use ISO 8601.
Back to section index