DocsAutomationWebhooks & Gateway

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 --gateway

The 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
RolePermissions
viewerRead 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/sessions

Response:

{
  "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/a1b2c3d4

GET /api/config

Get the current configuration (API keys redacted):

curl -H "Authorization: Bearer $RYVOS_API_KEY" \
  http://localhost:18789/api/config

POST /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 TypeDescription
RunStartedNew run started
TextDeltaStreaming text fragment
ToolStartTool execution beginning
ToolEndTool execution complete
TurnCompleteOne ReAct turn finished
RunCompleteRun finished
RunErrorRun failed with error
ApprovalRequestedTool needs approval
ApprovalResolvedApproval granted or denied
GuardianHintGuardian injected a hint
HeartbeatAlertHeartbeat detected an issue
CronFiredCron job triggered
BudgetWarningApproaching 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"}'
fi

CORS

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