Overview
The listen command connects to ModelRiver via WebSocket and receives webhook events in real-time. Unlike traditional webhooks that require a publicly accessible URL, this approach works entirely through WebSocket: no ngrok, no public URL, no firewall configuration.
Usage
Bash
# Start listening for webhooks (like `stripe listen`)modelriver listen --print # Forward to local servermodelriver listen --port 3001 --print # With custom API keymodelriver listen --api-key mr_live_YOUR_KEY --print # Forward to external server (without starting local server)modelriver listen --port 3002 --forward --printHow it works
- Authenticates with your API key
- Gets a secure WebSocket token (valid for 24 hours)
- Connects to ModelRiver via WebSocket
- Receives webhook events in real-time: no public URL or ngrok required!
- Optionally forwards to local server
Example output
✓ Connecting to ModelRiver...✓ WebSocket connected✓ Joined webhook channel > Ready! Listening for webhook events> User ID: user-id-123> Channel: cli_webhooks:user-id-123> Local port: 3001 > Press Ctrl+C to stop [2026-01-07 15:20:30] Webhook received via WebSocket: Channel ID: abc-123-def Status: success Data: {"result": "..."}Event-driven webhooks
When the workflow is event-driven, listen --print shows the intermediate payload and a callback hint:
[timestamp] Webhook received via WebSocket: Channel ID: abc-123-def Status: ai_generated (callback required) Type: task.ai_generated Event: schema_result_ready Callback URL: https://api.modelriver.com/v1/callback/abc-123-def Customer data: { "ticket_id": "TCK-10042" } AI response: { ... } > Event-driven webhook — complete the flow with a callback:> modelriver callback --channel-id abc-123-def --data '{"summary":"..."}'Then complete the flow with Callback.
Options
| Option | Description |
|---|---|
--print | Print received webhooks to console |
--port <number> | Local server port to forward to |
--forward | Enable forwarding to local server |
--api-key <key> | ModelRiver API key |
--verbose | Show detailed logs |