Gateway API
REST API gateway for external programs to interact with xopc.
Start Gateway
Foreground Mode (Recommended)
xopc gateway --port 18790Default port: 18790
The gateway runs in foreground mode by default. Press Ctrl+C to stop.
Force Start
If the port is already in use:
xopc gateway --forceThis will:
- Send SIGTERM to processes listening on the port
- Wait 700ms for graceful shutdown
- Send SIGKILL if still running
- Start the new gateway instance
Process Management Commands
Check Status
xopc gateway statusExample output:
✅ Gateway is running
Port: 18790
🌐 Access:
URL: http://localhost:18790
Token: abc12345...xyz67890
📝 Management:
xopc gateway stop # Stop gateway
xopc gateway restart # Restart gatewayStop Gateway
# Graceful stop (SIGTERM with 5 second timeout)
xopc gateway stop
# Force stop (SIGKILL immediately)
xopc gateway stop --force
# Custom timeout (milliseconds)
xopc gateway stop --timeout 3000Restart Gateway
# Send SIGUSR1 signal to trigger graceful restart
xopc gateway restart
# Force restart (kill and start new)
xopc gateway restart --forceNote: SIGUSR1 restart requires
XOPC_ALLOW_SIGUSR1_RESTART=1environment variable.
View Logs
# View last 50 lines
xopc gateway logs
# View specific number of lines
xopc gateway logs --lines 100
# Follow logs in real-time (like tail -f)
xopc gateway logs --followSystem Service Management
xopc supports running the gateway as a system service for automatic startup.
Supported Platforms
| Platform | Service Type |
|---|---|
| Linux | systemd user service |
| macOS | LaunchAgent |
| Windows | Task Scheduler |
Install as System Service
xopc gateway installOptions:
| Option | Description |
|---|---|
--port <number> | Gateway port (default: 18790) |
--host <address> | Host to bind to (default: 0.0.0.0) |
--token <token> | Authentication token |
--runtime <runtime> | Runtime: node or binary |
Example:
xopc gateway install --port 8080 --token my-secret-tokenAfter installation, the gateway will start automatically when you log in.
Service Commands
# Start via system service
xopc gateway service-start
# Check service status
xopc gateway service-status
# Uninstall system service
xopc gateway uninstallProcess Architecture
Gateway Lock
Uses file-based locking instead of PID files:
- Location:
~/.xopc/locks/gateway.{hash}.lock - Hash: SHA256 of config path (supports multiple configs)
- Content:
{ pid, createdAt, configPath, startTime }
Run Loop
┌─────────────────────────────────────────┐
│ Run Loop │
├─────────────────────────────────────────┤
│ 1. Acquire Gateway Lock │
│ 2. Start Gateway Server │
│ 3. Wait for signal │
│ - SIGTERM/SIGINT -> Stop │
│ - SIGUSR1 -> Restart │
│ 4. Graceful shutdown (5s timeout) │
│ 5. Release lock │
│ 6. Exit or respawn │
└─────────────────────────────────────────┘Process Respawn
On restart:
- Detect environment (supervised vs normal)
- If supervised: exit and let supervisor restart
- If normal: spawn detached child, then exit
Port Management
# Check if port is available
lsof -i :18790
# Force free port (SIGTERM -> SIGKILL)
xopc gateway --forceAPI Endpoints
Send Message
POST /api/message
Content-Type: application/json
{
"channel": "telegram",
"chat_id": "123456789",
"content": "Hello from API!",
"accountId": "personal"
}Response:
{
"status": "ok",
"message_id": "abc123"
}Send Message (Sync)
POST /api/message/sync
Content-Type: application/json
{
"channel": "telegram",
"chat_id": "123456789",
"content": "Hello and reply!"
}Response:
{
"status": "ok",
"reply": "Hello! How can I help?"
}Agent Chat
POST /api/agent
Content-Type: application/json
{
"message": "What is the weather?",
"session": "default"
}Response:
{
"status": "ok",
"reply": "The weather is sunny...",
"session": "default"
}Trigger Cron Job
POST /api/cron/trigger
Content-Type: application/json
{
"job_id": "abc123"
}Response:
{
"status": "ok",
"message": "Task triggered"
}Health Check
GET /healthResponse:
{
"status": "healthy",
"uptime": 3600
}Create session (POST /api/sessions)
Creates a webchat-scoped session (or returns an existing empty one). JSON body (all optional except as noted):
| Field | Description |
|---|---|
channel | Source label for the session key (default webchat). |
chat_id | If set, forces a session key with this peer id. |
agentId | If set, must match an enabled id in agents.list; session key uses this agent. If omitted, uses agents.default or the first enabled list entry (see Session Routing). |
Complete API List
| Method | Path | Description |
|---|---|---|
| POST | /api/message | Send message (async) |
| POST | /api/message/sync | Send message (sync) |
| POST | /api/agent | Agent chat |
| POST | /api/sessions | Create or reuse a webchat session (optional agentId in JSON body) |
| GET | /api/sessions | List sessions |
| GET | /api/sessions/:key | Get session |
| DELETE | /api/sessions/:key | Delete session |
| GET | /api/cron | List scheduled tasks |
| POST | /api/cron/trigger | Trigger task |
| GET | /health | Health check |
| GET | /api/logs | Query logs (auth required) |
| POST | /api/cron/create | Create scheduled task |
| DELETE | /api/cron/:id | Delete scheduled task |
| POST | /api/cron/:id/toggle | Enable/disable task |
| GET | /api/providers | List LLM providers |
| GET | /api/models | List available models |
| GET | /api/models-json | Get models.json config |
| PATCH | /api/models-json | Save models.json |
Error Responses
All API errors follow this format:
{
"error": {
"code": "INVALID_REQUEST",
"message": "Invalid message content"
}
}Error codes:
| Error Code | Description |
|---|---|
INVALID_REQUEST | Invalid request parameters |
CHANNEL_NOT_FOUND | Channel not found |
SESSION_NOT_FOUND | Session not found |
AGENT_ERROR | Agent processing error |
INTERNAL_ERROR | Internal error |
Usage Examples
cURL
# Send message
curl -X POST http://localhost:18790/api/message \
-H "Content-Type: application/json" \
-d '{"channel": "telegram", "chat_id": "123", "content": "Hello!"}'
# Agent chat
curl -X POST http://localhost:18790/api/agent \
-H "Content-Type: application/json" \
-d '{"message": "What is 2+2?"}'
# Health check
curl http://localhost:18790/health
# Request with auth
curl -X POST http://localhost:18790/api/agent \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"message": "Hello"}'JavaScript/Node.js
async function sendMessage(content, chatId) {
const res = await fetch('http://localhost:18790/api/message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
channel: 'telegram',
chat_id: chatId,
content: content
})
});
return res.json();
}
async function chatWithAgent(message) {
const res = await fetch('http://localhost:18790/api/agent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
return res.json();
}Python
import requests
def send_message(content, chat_id):
resp = requests.post(
'http://localhost:18790/api/message',
json={
'channel': 'telegram',
'chat_id': chat_id,
'content': content
}
)
return resp.json()
def chat(message):
resp = requests.post(
'http://localhost:18790/api/agent',
json={'message': message}
)
return resp.json()Authentication
⚠️ Current version has no API authentication enabled by default.
For production, recommended:
- Add Basic Auth via Nginx/Traefik
- Or configure API Key via config
- Limit accessible IPs
Configure Auth
{
"gateway": {
"auth": {
"enabled": true,
"api_key": "your-secret-token"
}
}
}Configuration
{
"gateway": {
"host": "0.0.0.0",
"port": 18790,
"auth": {
"enabled": true,
"api_key": "your-secret-token"
},
"cors": {
"enabled": true,
"origins": ["http://localhost:3000"]
}
}
}| Parameter | Default | Description |
|---|---|---|
host | 0.0.0.0 | Bind address |
port | 18790 | Port number |
auth.enabled | false | Enable authentication |
auth.api_key | null | API auth token |
cors.enabled | false | Enable CORS |
cors.origins | [] | Allowed origins |
Graceful Shutdown
Gateway supports graceful shutdown:
- After receiving stop signal, wait 5 seconds for existing requests
- If requests still pending after 5 seconds, force terminate
- Automatically release lock file
Timeout can be customized:
xopc gateway stop --timeout 10000 # 10 second timeoutEnvironment Variables
| Variable | Description |
|---|---|
XOPC_NO_RESPAWN | Disable process respawn |
XOPC_ALLOW_SIGUSR1_RESTART | Allow SIGUSR1 to trigger restart |
XOPC_SERVICE_MARKER | Mark running under supervisor |
CORS Configuration
To access from browser, add CORS headers:
{
"gateway": {
"cors": {
"enabled": true,
"origins": ["http://localhost:3000"],
"credentials": true
}
}
}Web UI
The gateway serves the Web UI at / (hash-router SPA; assets under /assets/*):
# Start gateway
xopc gateway
# Open in browser
open http://localhost:18790/Features:
- Real-time chat with WebSocket
- Session management
- Configuration dialog
- Log viewer
- Cron job management
- Models configuration
Troubleshooting
Port Already in Use
# Check what's using the port
lsof -i :18790
# Force start (kills existing process)
xopc gateway --forceGateway Won't Start
- Check logs:
xopc gateway logs - Verify config is valid JSON
- Check if lock file exists:
~/.xopc/locks/ - Remove stale lock file if needed
API Not Responding
- Check gateway status:
xopc gateway status - Verify port is correct
- Check firewall settings
- Review gateway logs for errors