Complete reference for the UROAM daemon (uroamd) JSON-RPC 2.0 API over Unix socket.
UROAM daemon (uroamd) exposes a JSON-RPC 2.0 API over a Unix domain socket for inter-process communication with the CLI tool (ramctl) and third-party applications.
- Protocol: JSON-RPC 2.0 (spec: jsonrpc.org)
- Transport: Unix domain socket
- Socket Location:
/run/uroam/uroamd.sock - Authentication: Unix socket permissions + PolicyKit (for privileged operations)
/run/uroam/uroamd.sock
# Check socket permissions
ls -l /run/uroam/uroamd.sock
# Typical output:
# srw-rw---- 1 uroam uroam 0 May 2 12:00 /run/uroam/uroamd.sock# Send a command
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | socat - UNIX-CONNECT:/run/uroam/uroamd.sock
# Monitor with continuous output
socat UNIX-CONNECT:/run/uroam/uroamd.sock -# Send a command
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | nc -U /run/uroam/uroamd.sockimport socket
import json
def uroam_request(method, params={}):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect('/run/uroam/uroamd.sock')
request = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": 1
}
sock.sendall(json.dumps(request).encode())
response = sock.recv(4096)
sock.close()
return json.loads(response)
# Example: get status
status = uroam_request("status")
print(json.dumps(status, indent=2))use std::os::unix::net::UnixStream;
use std::io::{Read, Write};
use serde_json::json;
fn uroam_request(method: &str, params: serde_json::Value) -> Result<String, Box<dyn std::error::Error>> {
let mut stream = UnixStream::connect("/run/uroam/uroamd.sock")?;
let request = json!({
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": 1
});
stream.write_all(request.to_string().as_bytes())?;
let mut response = String::new();
stream.read_to_string(&mut response)?;
Ok(response)
}{
"jsonrpc": "2.0",
"method": "<command_name>",
"params": {
// Command-specific parameters
},
"id": <request_id>
}{
"jsonrpc": "2.0",
"result": {
// Command-specific result data
},
"id": <request_id>
}{
"jsonrpc": "2.0",
"error": {
"code": <error_code>,
"message": "<error_message>",
"data": {
// Optional additional error details
}
},
"id": <request_id>
}Get current system memory status, workload classification, and optimization state.
{
"jsonrpc": "2.0",
"method": "status",
"params": {
"verbose": false
},
"id": 1
}| Parameter | Type | Required | Description |
|---|---|---|---|
| verbose | boolean | No | Include detailed per-process information |
{
"jsonrpc": "2.0",
"result": {
"memory": {
"total": 16777216,
"used": 8388608,
"available": 8388608,
"used_percent": 50.0,
"swap_total": 4194304,
"swap_used": 1048576,
"swap_used_percent": 25.0
},
"zram": {
"enabled": true,
"algorithm": "lz4",
"size_mb": 8192,
"used_mb": 2048,
"compression_ratio": 2.5
},
"zswap": {
"enabled": true,
"compressor": "lz4",
"pool_percent": 20
},
"workload": {
"type": "gaming",
"priority": 0,
"confidence": 0.95,
"active_processes": 3
},
"optimizations": {
"swappiness": 1,
"thp_mode": "always",
"ksm_enabled": false,
"cache_pressure": 50
},
"profile": "gaming",
"idle": false
},
"id": 1
}Trigger immediate memory optimization pass.
{
"jsonrpc": "2.0",
"method": "optimize",
"params": {
"level": "normal"
},
"id": 2
}| Parameter | Type | Required | Description |
|---|---|---|---|
| level | string | No | Optimization level: "light", "normal", "aggressive" (default: "normal") |
{
"jsonrpc": "2.0",
"result": {
"success": true,
"actions_taken": [
"Set swappiness to 1",
"Enabled THP",
"Dropped page caches"
],
"memory_freed_mb": 512,
"duration_ms": 150
},
"id": 2
}Set the active optimization profile.
{
"jsonrpc": "2.0",
"method": "profile_set",
"params": {
"profile": "gaming"
},
"id": 3
}| Parameter | Type | Required | Description |
|---|---|---|---|
| profile | string | Yes | Profile name: "ai", "gaming", "balanced", "powersaver" |
{
"jsonrpc": "2.0",
"result": {
"success": true,
"previous_profile": "balanced",
"active_profile": "gaming",
"settings_applied": {
"swappiness": 1,
"zram_algorithm": "lz4",
"zram_size_percent": 30,
"ksm_enabled": false,
"thp_mode": "always"
}
},
"id": 3
}Get the currently active profile and its settings.
{
"jsonrpc": "2.0",
"method": "profile_get",
"params": {},
"id": 4
}{
"jsonrpc": "2.0",
"result": {
"active_profile": "gaming",
"settings": {
"swappiness": 1,
"zram_algorithm": "lz4",
"zram_size_percent": 30,
"ksm_enabled": false,
"thp_mode": "always",
"cache_pressure": 50
},
"available_profiles": ["ai", "gaming", "balanced", "powersaver"]
},
"id": 4
}Perform aggressive memory cleanup (drops caches, compacts memory, triggers KSM).
{
"jsonrpc": "2.0",
"method": "clean",
"params": {
"confirm": true,
"level": "normal"
},
"id": 5
}| Parameter | Type | Required | Description |
|---|---|---|---|
| confirm | boolean | Yes | Must be true to confirm the operation |
| level | string | No | Cleanup level: "light", "normal", "aggressive" (default: "normal") |
{
"jsonrpc": "2.0",
"result": {
"success": true,
"actions_taken": [
"Dropped page caches (level 3)",
"Compacted memory",
"Triggered KSM scan"
],
"memory_freed_mb": 1024,
"caches_dropped_mb": 512
},
"id": 5
}Start real-time monitoring mode (streaming responses).
{
"jsonrpc": "2.0",
"method": "monitor",
"params": {
"interval_ms": 1000,
"duration_secs": 0
},
"id": 6
}| Parameter | Type | Required | Description |
|---|---|---|---|
| interval_ms | integer | No | Update interval in milliseconds (default: 1000) |
| duration_secs | integer | No | Monitoring duration (0 = indefinite) |
The monitor command sends multiple responses at the specified interval:
{
"jsonrpc": "2.0",
"result": {
"timestamp": "2026-05-02T12:00:00Z",
"memory": {
"used_percent": 50.0,
"swap_used_percent": 25.0
},
"psi": {
"some_10": 2.5,
"some_60": 1.8,
"some_300": 1.2
},
"workload": {
"type": "gaming",
"priority": 0
}
},
"id": 6
}Note: To stop monitoring, send a SIGINT (Ctrl+C) or close the socket connection.
Get ZRAM device status and statistics.
{
"jsonrpc": "2.0",
"method": "zram_status",
"params": {},
"id": 7
}{
"jsonrpc": "2.0",
"result": {
"enabled": true,
"devices": [
{
"device": "/dev/zram0",
"algorithm": "lz4",
"disksize_mb": 8192,
"compr_data_size_mb": 2048,
"mem_used_total_mb": 512,
"compression_ratio": 4.0,
"num_reads": 1000,
"num_writes": 5000
}
],
"total_stats": {
"original_mb": 8192,
"compressed_mb": 2048,
"savings_mb": 6144,
"savings_percent": 75.0
}
},
"id": 7
}Reload configuration from /etc/uroam/uroam.toml.
{
"jsonrpc": "2.0",
"method": "config_reload",
"params": {},
"id": 8
}{
"jsonrpc": "2.0",
"result": {
"success": true,
"config_path": "/etc/uroam/uroam.toml",
"changes_applied": [
"Updated polling interval to 500ms",
"Applied new ZRAM settings"
],
"warnings": []
},
"id": 8
}If the configuration file has errors:
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid configuration",
"data": {
"line": 15,
"field": "zram.size_percent",
"error": "Value must be between 0 and 100"
}
},
"id": 8
}Gracefully stop the UROAM daemon.
{
"jsonrpc": "2.0",
"method": "daemon_stop",
"params": {
"force": false
},
"id": 9
}| Parameter | Type | Required | Description |
|---|---|---|---|
| force | boolean | No | Force stop without cleanup (default: false) |
{
"jsonrpc": "2.0",
"result": {
"success": true,
"message": "Daemon stopping gracefully",
"cleanup_actions": [
"Restored swappiness to 60",
"Disabled KSM",
"Reset THP to madvise"
]
},
"id": 9
}UROAM uses standard JSON-RPC 2.0 error codes with custom extensions.
| Code | Message | Description |
|---|---|---|
| -32700 | Parse error | Invalid JSON was received |
| -32600 | Invalid Request | The JSON sent is not a valid Request object |
| -32601 | Method not found | The method does not exist / is not available |
| -32602 | Invalid params | Invalid method parameters |
| -32603 | Internal error | Internal JSON-RPC error |
| Code | Message | Description |
|---|---|---|
| 1000 | Daemon not initialized | Daemon is still initializing |
| 1001 | Profile not found | Specified profile does not exist |
| 1002 | Invalid profile settings | Profile settings are invalid |
| 1003 | Optimization failed | Memory optimization could not be applied |
| 1004 | ZRAM error | ZRAM device error (not available, full, etc.) |
| 1005 | Permission denied | Insufficient privileges for operation |
| 1006 | Config error | Configuration file error |
| 1007 | Socket error | Unix socket communication error |
| 1008 | Workload detection failed | Could not classify current workload |
{
"jsonrpc": "2.0",
"error": {
"code": -32700,
"message": "Parse error",
"data": {
"detail": "Unexpected token ':' at position 25"
}
},
"id": null
}{
"jsonrpc": "2.0",
"error": {
"code": -32601,
"message": "Method not found",
"data": {
"method": "unknown_command"
}
},
"id": 10
}{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"field": "profile",
"expected": ["ai", "gaming", "balanced", "powersaver"],
"received": "invalid_profile"
}
},
"id": 11
}{
"jsonrpc": "2.0",
"error": {
"code": 1005,
"message": "Permission denied",
"data": {
"operation": "profile_set",
"required_capability": "CAP_SYS_ADMIN",
"hint": "Run with sudo or use PolicyKit authentication"
}
},
"id": 12
}The ramctl CLI tool handles all JSON-RPC communication for you:
# Get status
ramctl status
# Get JSON output
ramctl status --json
# Set profile
ramctl profile set gaming
# Trigger optimization
ramctl optimize
# Monitor in real-time
ramctl monitor --interval 2
# Clean memory
ramctl clean
# Reload configuration
ramctl config reload# Wrap curl-like syntax with socat
alias uroam-call='socat -T2 UNIX-CONNECT:/run/uroam/uroamd.sock -'
# Get status
echo '{"jsonrpc":"2.0","method":"status","params":{},"id":1}' | uroam-call
# Set profile
echo '{"jsonrpc":"2.0","method":"profile_set","params":{"profile":"gaming"},"id":2}' | uroam-call
# Trigger optimization
echo '{"jsonrpc":"2.0","method":"optimize","params":{},"id":3}' | uroam-call#!/usr/bin/env python3
import socket
import json
import sys
class UroamClient:
def __init__(self, socket_path="/run/uroam/uroamd.sock"):
self.socket_path = socket_path
self.request_id = 0
def _call(self, method, params={}):
self.request_id += 1
request = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": self.request_id
}
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect(self.socket_path)
sock.sendall(json.dumps(request).encode() + b'\n')
response = b""
while True:
chunk = sock.recv(4096)
if not chunk:
break
response += chunk
if b'\n' in chunk:
break
sock.close()
return json.loads(response.decode())
except Exception as e:
return {"error": str(e)}
def status(self):
return self._call("status")
def optimize(self):
return self._call("optimize")
def set_profile(self, profile):
return self._call("profile_set", {"profile": profile})
def get_profile(self):
return self._call("profile_get")
def clean(self):
return self._call("clean", {"confirm": True})
if __name__ == "__main__":
client = UroamClient()
if len(sys.argv) < 2:
print("Usage: uroam_client.py <status|optimize|profile_set|clean>")
sys.exit(1)
command = sys.argv[1]
if command == "status":
result = client.status()
elif command == "optimize":
result = client.optimize()
elif command == "profile_set":
if len(sys.argv) < 3:
print("Usage: uroam_client.py profile_set <profile_name>")
sys.exit(1)
result = client.set_profile(sys.argv[2])
elif command == "clean":
result = client.clean()
else:
print(f"Unknown command: {command}")
sys.exit(1)
print(json.dumps(result, indent=2))#!/bin/bash
# uroam-api.sh - Simple bash client for UROAM API
SOCKET="/run/uroam/uroamd.sock"
ID=0
uroam_call() {
local method="$1"
local params="$2"
((ID++))
local request="{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":$params,\"id\":$ID}"
echo "$request" | socat -T2 UNIX-CONNECT:"$SOCKET" -
}
# Get status
uroam_call "status" "{}"
# Set profile
uroam_call "profile_set" "{\"profile\":\"gaming\"}"
# Trigger optimization
uroam_call "optimize" "{}"- User Guide - Learn how to use
ramctlCLI - Developer Guide - Integrate UROAM into your applications
- Installation Guide - Install UROAM on your system