Config API
Manage per-user agent configuration with automatic versioned backups. Configuration is persisted in the database and survives server restarts. The system keeps the last 10 configuration backups and allows restoring to any previous version.All Config API endpoints require authentication. Include a valid session cookie or auth token with every request. Unauthenticated requests receive a
401 Unauthorized response.Get current configuration
GET /api/config
Response
{
"config": {
"logging": { "level": "info" },
"agents": {
"defaults": {
"workspace": "/home/node/.openclaw/workspace",
"model": { "primary": "openrouter/xiaomi/mimo-v2-pro" },
"heartbeat": { "every": "30m", "lightContext": true, "isolatedSession": true }
}
},
"tools": {
"profile": "coding",
"exec": { "backgroundMs": 10000, "timeoutSec": 1800 },
"web": {
"search": { "enabled": true },
"fetch": { "enabled": true, "maxChars": 50000 }
}
},
"gateway": {
"bind": "lan",
"auth": { "mode": "token" }
},
"channels": {
"telegram": { "enabled": false, "dmPolicy": "pairing" },
"discord": { "enabled": false, "dmPolicy": "pairing" },
"whatsapp": { "enabled": false, "dmPolicy": "pairing" },
"webchat": { "enabled": true }
},
"cron": { "enabled": true, "maxConcurrentRuns": 2, "sessionRetention": "24h" },
"session": {
"scope": "per-sender",
"reset": { "mode": "daily", "atHour": 4 },
"maintenance": { "mode": "warn", "pruneAfter": "30d", "maxEntries": 500 }
},
"skills": {
"install": { "nodeManager": "npm" }
}
},
"backups": [
{
"id": "bkp_initial",
"timestamp": "2026-03-27T10:00:00Z"
}
]
}
| Field | Type | Description |
|---|---|---|
config | object | The current agent configuration |
config.logging.level | string | Log level (e.g. "info", "debug", "warn") |
config.agents.defaults.workspace | string | Path to the agent’s workspace directory |
config.agents.defaults.model.primary | string | Default AI model identifier |
config.agents.defaults.heartbeat.every | string | Heartbeat interval (e.g. "30m") |
config.agents.defaults.heartbeat.lightContext | boolean | Use lightweight context during heartbeat checks |
config.agents.defaults.heartbeat.isolatedSession | boolean | Run heartbeat checks in an isolated session |
config.tools.profile | string | Tool profile ("coding" for collective+ plans, "messaging" for solo) |
config.tools.exec.backgroundMs | number | Maximum time in milliseconds for background execution tasks |
config.tools.exec.timeoutSec | number | Maximum execution timeout in seconds |
config.tools.web.search.enabled | boolean | Whether web search is available to the agent |
config.tools.web.fetch.enabled | boolean | Whether web fetch is available to the agent |
config.tools.web.fetch.maxChars | number | Maximum characters returned from a web fetch |
config.gateway.bind | string | Gateway bind address (e.g. "lan" for all interfaces) |
config.gateway.auth.mode | string | Gateway authentication mode (e.g. "token") |
config.channels | object | Channel-specific settings |
config.channels.telegram.enabled | boolean | Whether the Telegram channel is active |
config.channels.telegram.dmPolicy | string | DM policy for Telegram ("pairing" or "allowlist") |
config.channels.discord.enabled | boolean | Whether the Discord channel is active |
config.channels.discord.dmPolicy | string | DM policy for Discord ("pairing" or "allowlist") |
config.channels.whatsapp.enabled | boolean | Whether the WhatsApp channel is active |
config.channels.whatsapp.dmPolicy | string | DM policy for WhatsApp ("pairing" or "allowlist") |
config.channels.webchat.enabled | boolean | Whether the webchat channel is active |
config.cron.enabled | boolean | Whether the cron scheduler is active |
config.cron.maxConcurrentRuns | number | Maximum concurrent cron job executions |
config.cron.sessionRetention | string | How long cron session data is retained |
config.session.scope | string | Session scope (e.g. "per-sender") |
config.session.reset.mode | string | Session reset mode (e.g. "daily") |
config.session.reset.atHour | number | Hour of day when daily session reset occurs (0-23) |
config.session.maintenance.mode | string | Maintenance mode ("warn" or "silent") |
config.session.maintenance.pruneAfter | string | Age after which sessions are eligible for pruning |
config.session.maintenance.maxEntries | number | Maximum number of session entries retained |
config.skills.install.nodeManager | string | Node package manager used for skill installation (e.g. "npm") |
backups | array | List of available backups (id and timestamp only) |
backups[].id | string | Unique backup identifier |
backups[].timestamp | string | ISO 8601 timestamp when the backup was created |
Errors
| Code | Description |
|---|---|
| 401 | Unauthorized — no valid session |
Save configuration
POST /api/config
Request body
| Field | Type | Required | Description |
|---|---|---|---|
config | object | Yes | The new configuration object to save. Must be a valid JSON object. |
Response
{
"success": true,
"config": { ... },
"backupId": "bkp_1711540800000",
"backups": [
{ "id": "bkp_1711540800000", "timestamp": "2026-03-27T12:00:00Z" },
{ "id": "bkp_initial", "timestamp": "2026-03-27T10:00:00Z" }
]
}
| Field | Type | Description |
|---|---|---|
success | boolean | true when the configuration was saved |
config | object | The newly saved configuration |
backupId | string | Identifier of the backup created from the previous configuration |
backups | array | Updated list of available backups (id and timestamp only) |
Errors
| Code | Description |
|---|---|
| 400 | Invalid config object — the config field is missing or is not an object |
| 400 | Config is not valid JSON — the config object cannot be serialized as valid JSON |
| 400 | Invalid request body — the request body is not valid JSON |
| 401 | Unauthorized — no valid session |
Restore a backup
PUT /api/config
Request body
| Field | Type | Required | Description |
|---|---|---|---|
backupId | string | Yes | The identifier of the backup to restore |
Response
{
"success": true,
"config": { ... },
"restoredFrom": "bkp_initial",
"backups": [
{ "id": "bkp_1711540800001", "timestamp": "2026-03-27T12:05:00Z" },
{ "id": "bkp_initial", "timestamp": "2026-03-27T10:00:00Z" }
]
}
| Field | Type | Description |
|---|---|---|
success | boolean | true when the configuration was restored |
config | object | The restored configuration |
restoredFrom | string | Identifier of the backup that was restored |
backups | array | Updated list of available backups (id and timestamp only) |
Errors
| Code | Description |
|---|---|
| 400 | Missing backupId — the backupId field is missing from the request body |
| 400 | Invalid request body — the request body is not valid JSON |
| 401 | Unauthorized — no valid session |
| 404 | Backup not found — no backup exists with the given identifier |
Example: save and restore
# Save a new configuration (requires authentication)
curl -X POST https://agentbot.raveculture.xyz/api/config \
-H "Content-Type: application/json" \
-H "Cookie: session=YOUR_SESSION_TOKEN" \
-d '{
"config": {
"logging": { "level": "debug" },
"agents": {
"defaults": {
"workspace": "/home/node/.openclaw/workspace",
"model": { "primary": "openrouter/xiaomi/mimo-v2-pro" },
"heartbeat": { "every": "30m", "lightContext": true, "isolatedSession": true }
}
},
"tools": {
"profile": "coding",
"exec": { "backgroundMs": 10000, "timeoutSec": 1800 },
"web": { "search": { "enabled": true }, "fetch": { "enabled": true, "maxChars": 50000 } }
},
"gateway": {
"bind": "lan",
"auth": { "mode": "token" }
},
"channels": {
"telegram": { "enabled": true, "dmPolicy": "pairing" },
"discord": { "enabled": false, "dmPolicy": "pairing" },
"whatsapp": { "enabled": false, "dmPolicy": "pairing" },
"webchat": { "enabled": true }
},
"cron": { "enabled": true, "maxConcurrentRuns": 2, "sessionRetention": "24h" },
"session": {
"scope": "per-sender",
"reset": { "mode": "daily", "atHour": 4 },
"maintenance": { "mode": "warn", "pruneAfter": "30d", "maxEntries": 500 }
},
"skills": {
"install": { "nodeManager": "npm" }
}
}
}'
# Restore from a backup (requires authentication)
curl -X PUT https://agentbot.raveculture.xyz/api/config \
-H "Content-Type: application/json" \
-H "Cookie: session=YOUR_SESSION_TOKEN" \
-d '{ "backupId": "bkp_initial" }'