The Ryvos gateway is an Axum HTTP/WebSocket server that provides programmatic access to the agent. It serves the Web UI, exposes a REST API, and supports real-time streaming via WebSocket.
Starting the Gateway
# Gateway only (no channels)
ryvos serve
# Gateway + all channels
ryvos daemon --gatewayThe gateway binds to 127.0.0.1:18789 by default.
[gateway]
bind = "127.0.0.1:18789"Authentication
The gateway uses API key authentication with three roles:
[[gateway.api_keys]]
key = "${RYVOS_ADMIN_KEY}"
role = "admin"
[[gateway.api_keys]]
key = "${RYVOS_OPERATOR_KEY}"
role = "operator"
[[gateway.api_keys]]
key = "${RYVOS_VIEWER_KEY}"
role = "viewer"Include the API key in requests:
curl -H "Authorization: Bearer $RYVOS_ADMIN_KEY" http://localhost:18789/api/sessions| Role | Permissions |
|---|---|
viewer | Read sessions, view metrics, view config (redacted) |
operator | + Send messages, create sessions, manage cron jobs |
admin | + Change config, manage API keys, full access |
REST API
POST /api/chat
Send a message and get a response:
curl -X POST http://localhost:18789/api/chat \
-H "Authorization: Bearer $RYVOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "What is the current disk usage?",
"session_id": "optional-session-id"
}'Response:
{
"session_id": "a1b2c3d4",
"response": "Current disk usage:\n/ — 42% used (84GB of 200GB)\n/home — 67% used (134GB of 200GB)",
"tools_used": ["bash"],
"tokens": { "input": 1240, "output": 156 },
"cost_cents": 0.8
}GET /api/sessions
List recent sessions:
curl -H "Authorization: Bearer $RYVOS_API_KEY" \
http://localhost:18789/api/sessionsResponse:
{
"sessions": [
{
"id": "a1b2c3d4",
"title": "Disk usage check",
"created_at": "2026-03-15T14:32:00Z",
"last_activity": "2026-03-15T14:32:07Z",
"message_count": 4
}
]
}GET /api/sessions/:id
Get session details and history:
curl -H "Authorization: Bearer $RYVOS_API_KEY" \
http://localhost:18789/api/sessions/a1b2c3d4GET /api/config
Get the current configuration (API keys redacted):
curl -H "Authorization: Bearer $RYVOS_API_KEY" \
http://localhost:18789/api/configPOST /api/hooks/wake
Webhook endpoint for external systems to trigger the agent:
curl -X POST http://localhost:18789/api/hooks/wake \
-H "Authorization: Bearer $RYVOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "The staging deploy just failed. Check the CI logs and diagnose.",
"channel": "slack",
"metadata": {
"source": "github-actions",
"run_id": "12345"
}
}'The wake endpoint starts a new agent session with the given prompt and optionally routes the response to a channel.
WebSocket Protocol
Connect to the WebSocket endpoint for real-time streaming:
ws://localhost:18789/ws?token=YOUR_API_KEY
Message Types
Request (Client → Server)
{
"type": "chat",
"session_id": "a1b2c3d4",
"message": "What is the disk usage?"
}Response (Server → Client)
Text delta (streaming):
{
"type": "delta",
"session_id": "a1b2c3d4",
"content": "Current disk"
}Tool execution:
{
"type": "tool_start",
"session_id": "a1b2c3d4",
"tool": "bash",
"input": { "command": "df -h" }
}{
"type": "tool_end",
"session_id": "a1b2c3d4",
"tool": "bash",
"result": "Filesystem Size Used Avail Use% ...",
"is_error": false
}Run complete:
{
"type": "run_complete",
"session_id": "a1b2c3d4",
"tokens": { "input": 1240, "output": 156 },
"cost_cents": 0.8
}Event Stream
The WebSocket also broadcasts AgentEvent variants (30+ types):
| Event Type | Description |
|---|---|
RunStarted | New run started |
TextDelta | Streaming text fragment |
ToolStart | Tool execution beginning |
ToolEnd | Tool execution complete |
TurnComplete | One ReAct turn finished |
RunComplete | Run finished |
RunError | Run failed with error |
ApprovalRequested | Tool needs approval |
ApprovalResolved | Approval granted or denied |
GuardianHint | Guardian injected a hint |
HeartbeatAlert | Heartbeat detected an issue |
CronFired | Cron job triggered |
BudgetWarning | Approaching budget limit |
Webhook Integration Examples
GitHub Actions
Trigger Ryvos when a CI/CD workflow fails:
# .github/workflows/notify-ryvos.yml
name: Notify Ryvos on Failure
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
notify:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
runs-on: ubuntu-latest
steps:
- run: |
curl -X POST https://your-server:18789/api/hooks/wake \
-H "Authorization: Bearer ${{ secrets.RYVOS_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{
"prompt": "CI failed on branch ${{ github.event.workflow_run.head_branch }}. Run ID: ${{ github.event.workflow_run.id }}. Check the logs and suggest a fix.",
"channel": "slack"
}'Monitoring (Uptime Robot, Pingdom, etc.)
Trigger Ryvos when a monitor detects downtime:
# Webhook URL in your monitoring tool:
# POST https://your-server:18789/api/hooks/wake
# Body template:
{
"prompt": "Alert: {{monitorFriendlyName}} is DOWN. URL: {{monitorURL}}. Reason: {{alertDetails}}. Investigate and report.",
"channel": "telegram"
}Custom Script
Trigger from any script:
#!/bin/bash
# deploy.sh — notify Ryvos after deployment
deploy_to_production
if [ $? -eq 0 ]; then
curl -X POST http://localhost:18789/api/hooks/wake \
-H "Authorization: Bearer $RYVOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Deployment complete. Run a health check on production.", "channel": "slack"}'
else
curl -X POST http://localhost:18789/api/hooks/wake \
-H "Authorization: Bearer $RYVOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "Deployment FAILED. Check the deploy logs and diagnose.", "channel": "telegram"}'
fiCORS
The gateway enables CORS for the Web UI. By default, it allows requests from localhost and the configured bind address. For custom domains:
[gateway]
bind = "0.0.0.0:18789"
# CORS is automatically configured for the Web UI:::caution
Binding to 0.0.0.0 exposes the gateway to the network. Always use API key authentication and consider a reverse proxy (nginx, caddy) with TLS for production.
:::
Next Steps
- Cron & Heartbeat — Automated scheduling
- Web UI Dashboard — The browser interface
- Systemd Service — Run the gateway as a service