Skip to content
Back to skills

076 Api 08930e20

ASecurity

Complete REST API and WebSocket reference for OpenBotX. ---

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 31, 2026
securitypythonapifrontend

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 076-api_08930e20 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 076 Api 08930e20?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 076 Api 08930e20
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-076-api-08930e20/badge)](https://www.skillsdirectory.com/skills/tools-only-076-api-08930e20)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# OpenBotX API Reference

Complete REST API and WebSocket reference for OpenBotX.

---

## Authentication

All endpoints (except `/api/auth/login`) require a valid JWT token passed in the `Authorization` header:

```
Authorization: Bearer <token>
```

---

## REST API

All endpoints are prefixed with `/api/`.

---

### Auth

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/auth/login` | Authenticate and obtain a JWT token |

**POST /api/auth/login**

No authentication required.

Request body:

```json
{
  "username": "string",
  "password": "string"
}
```

Response:

```json
{
  "token": "string"
}
```

---

### System

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/health` | Health check |
| GET | `/api/version` | Server version |
| GET | `/api/system/info` | System information (OS, CPU, memory, disk, GPU) |

**GET /api/health**

Response:

```json
{
  "status": "ok",
  "version": "string"
}
```

**GET /api/version**

Response:

```json
{
  "version": "string"
}
```

**GET /api/system/info**

Response:

```json
{
  "os": { "system": "string", "release": "string", "version": "string", "machine": "string" },
  "cpu": { "processor": "string", "cores": 0 },
  "memory": { "total_gb": 0.0 },
  "disk": { "total_gb": 0.0, "used_gb": 0.0, "free_gb": 0.0, "percent": 0.0 },
  "gpu": [{ "name": "string" }],
  "python": "string",
  "version": "string"
}
```

---

### Chat

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/chat` | Send a message to the agent |
| POST | `/api/chat/upload` | Upload media files (images, audio) |
| GET | `/api/chat/sessions` | List all chat sessions |
| GET | `/api/chat/sessions/{session_id}` | Get a single session with messages |
| DELETE | `/api/chat/sessions/{session_id}` | Delete a session |

**POST /api/chat**

Sends a message asynchronously. The response is delivered via WebSocket events.

Request body:

```json
{
  "message": "string",
  "session_id": "string (optional)",
  "media": ["string (optional)"]
}
```

The `media` field accepts an array of storage paths (e.g., from `/api/chat/upload`). Images are sent to the LLM as data URIs. Audio files are transcribed via faster-whisper and the transcript is prepended to the message content.

The message is persisted to the session immediately (before the async agent loop processes it). This means a page refresh always shows the session and the user's message, even if the agent hasn't responded yet.

Response:

```json
{
  "task_id": "string",
  "session_id": "string"
}
```

**POST /api/chat/upload**

Upload media files (images, audio). Accepts multipart form data. Files are stored in date-organized subdirectories under `public/media/` (e.g., `public/media/2026/02/26/`) with a generated filename.

Request: `multipart/form-data` with one or more file fields.

Response:

```json
{
  "paths": ["public/media/2026/02/26/abc123def456.jpg"]
}
```

The returned paths can be passed in the `media` field of `POST /api/chat`.

**GET /api/chat/sessions**

Response:

```json
[
  {
    "key": "string",
    "created_at": "string",
    "updated_at": "string"
  }
]
```

**GET /api/chat/sessions/{session_id}**

The `session_id` is resolved using key resolution:
- If it contains `:`, used as the session key directly (e.g., `web:abc123`, `heartbeat:heartbeat`)
- Otherwise, prefixed with `web:` (standard user sessions)

Response:

```json
{
  "key": "string",
  "messages": [],
  "created_at": "string",
  "updated_at": "string"
}
```

**DELETE /api/chat/sessions/{session_id}**

Uses the same key resolution as GET.

Response:

```json
{
  "status": "deleted"
}
```

---

### Tasks

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/tasks` | List active tasks (done/error tasks older than 24h are excluded) |
| GET | `/api/tasks/{task_id}` | Get a single task |
| PATCH | `/api/tasks/{task_id}` | Update task state |

**GET /api/tasks**

Returns all `TODO` and `DOING` tasks, plus `DONE` and `ERROR` tasks from the last 24 hours.

**PATCH /api/tasks/{task_id}**

Request body:

```json
{
  "state": "TODO | DOING | DONE | ERROR"
}
```

---

### Files

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/files` | Get workspace file tree |
| GET | `/api/files/{path}` | Read file metadata or content |
| GET | `/api/files/download/{path}` | Download raw file |
| POST | `/api/files/create/{path}` | Create an empty file |
| POST | `/api/files/mkdir/{path}` | Create a directory |
| POST | `/api/files/upload/{path}` | Upload files to a directory |
| POST | `/api/files/upload` | Upload files to the root directory |
| PUT | `/api/files/{path}` | Write content to a file |
| DELETE | `/api/files/{path}` | Delete a file or directory (recursive) |

**GET /api/files**

Returns a recursive tree of the workspace directory (excluding hidden files, system files, and protected files like `config.yml`).

**GET /api/files/{path}**

Returns file info. The response format depends on the file type:

For text files (`.md`, `.txt`, `.json`, `.yaml`, `.py`, `.js`, `.html`, etc.):

```json
{
  "path": "string",
  "type": "text",
  "content": "string"
}
```

For media and binary files (`image`, `video`, `audio`, `binary`):

```json
{
  "path": "string",
  "type": "image | video | audio | binary",
  "mime": "string",
  "size": 0,
  "url": "string"
}
```

The `url` field points to `/public/{path}` for files under the `public/` directory (no auth required, suitable for `<img>`, `<video>`, `<audio>` tags), or `/api/files/download/{path}` for other files.

**POST /api/files/create/{path}**

Creates an empty file at the specified path. Parent directories are created automatically.

Response:

```json
{
  "status": "created"
}
```

**POST /api/files/mkdir/{path}**

Creates a directory at the specified path. Parent directories are created automatically.

Response:

```json
{
  "status": "created"
}
```

**POST /api/files/upload/{path}**

Upload files to the specified directory. Accepts multipart form data. `POST /api/files/upload` uploads to the root directory.

Request: `multipart/form-data` with one or more file fields.

Response:

```json
{
  "status": "ok",
  "paths": ["path/to/uploaded_file.txt"]
}
```

**GET /api/files/download/{path}**

Returns the raw file as a binary download. Requires authentication.

**PUT /api/files/{path}**

Request body:

```json
{
  "content": "string"
}
```

**DELETE /api/files/{path}**

Deletes a file or directory. Directories are deleted recursively.

Response:

```json
{
  "status": "deleted"
}
```

---

### Public Files

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/public/{path}` | Serve files from the `public/` directory |

No authentication required. Files under the project's `public/` directory are served directly. This allows media files (images, video, audio) to be rendered in HTML5 tags without needing auth headers.

---

### Skills

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/skills` | List all available skills |
| GET | `/api/skills/{name}` | Get skill content by name |

**GET /api/skills**

Response:

```json
[
  {
    "name": "string",
    "description": "string",
    "always": "boolean",
    "requires": "string[]"
  }
]
```

**GET /api/skills/{name}**

Response:

```json
{
  "name": "string",
  "content": "string"
}
```

---

### Channels

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/channels` | Get status of all channels |
| GET | `/api/channels/{name}` | Get channel details |
| PUT | `/api/channels/{name}` | Update channel configuration |
| POST | `/api/channels/{name}/start` | Start a channel |
| POST | `/api/channels/{name}/stop` | Stop a channel |

**GET /api/channels**

Response:

```json
{
  "web": {
    "running": "boolean"
  },
  "telegram": {
    "running": "boolean",
    "type": "string",
    "enabled": "boolean"
  }
}
```

**PUT /api/channels/{name}**

Request body:

```json
{
  "config": {
    "credential": "string",
    "allowed_users": ["string"],
    "...": "..."
  }
}
```

**POST /api/channels/{name}/start**

Starts the channel. For Telegram, also persists `enabled: true` to `config.yml` so the channel auto-starts on the next server boot.

Response:

```json
{
  "status": "started"
}
```

**POST /api/channels/{name}/stop**

Stops the channel. For Telegram, also persists `enabled: false` to `config.yml` so the channel stays stopped on the next server boot.

Response:

```json
{
  "status": "stopped"
}
```

---

### Credentials

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/credentials` | List all credentials (sensitive values masked) |
| POST | `/api/credentials` | Create a new credential |
| PUT | `/api/credentials/{name}` | Update a credential |
| DELETE | `/api/credentials/{name}` | Delete a credential |

**GET /api/credentials**

Response:

```json
[
  {
    "name": "string",
    "type": "string",
    "...": "type-specific fields (sensitive values masked)"
  }
]
```

**POST /api/credentials**

Request body:

```json
{
  "name": "string",
  "type": "string",
  "...": "type-specific fields"
}
```

**PUT /api/credentials/{name}**

Request body:

```json
{
  "type": "string",
  "...": "type-specific fields"
}
```

**DELETE /api/credentials/{name}**

Response:

```json
{
  "status": "deleted"
}
```

---

### Providers

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/providers` | List all LLM providers |
| PUT | `/api/providers/{name}` | Update provider configuration |

**GET /api/providers**

Response:

```json
[
  {
    "name": "string",
    "configured": "boolean",
    "credential": "string",
    "has_key": "boolean",
    "base_url": "string",
    "request_headers": {},
    "request_options": {},
    "model_params": {}
  }
]
```

**PUT /api/providers/{name}**

Request body:

```json
{
  "credential": "string",
  "base_url": "string",
  "request_headers": {},
  "request_options": {},
  "model_params": {}
}
```

---

### Agents

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/agents` | List all configured agents |

**GET /api/agents**

Response:

```json
[
  {
    "name": "string",
    "description": "string",
    "model": "string"
  }
]
```

---

### Tools

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/tools` | List all registered tools |

**GET /api/tools**

Response:

```json
[
  {
    "name": "string",
    "description": "string",
    "parameters": {}
  }
]
```

---

### Forms

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/forms` | Get dynamic form schemas for the frontend |

**GET /api/forms**

Returns form schema definitions used by the frontend's `DynamicForm` component to render configuration forms dynamically.

Each field in the schema has `name`, `type`, `label`, and optional `required`, `placeholder`, `options` (for select), and `visible_when` (conditional visibility).

Supported field types:

| Type | Component | Description |
|------|-----------|-------------|
| `text` | InputText | Standard text input |
| `email` | InputText | Email input |
| `int` | InputNumber | Integer input |
| `float` | InputNumber | Decimal input |
| `bool` | ToggleSwitch | Boolean toggle |
| `secret` | Password | Masked input with toggle |
| `long-text` | Textarea | Multi-line text |
| `select` | Select | Dropdown with static options |
| `credential` | Select | Dropdown of available credentials |
| `provider` | Select | Dropdown of available providers |
| `datetime` | DatePicker | Date and time picker |
| `date` | DatePicker | Date only picker |
| `time` | DatePicker | Time only picker (24h) |
| `color` | ColorPicker | Color selector |

Response:

```json
{
  "form_name": [
    { "name": "field_name", "type": "text", "label": "Field Label", "required": true }
  ]
}
```

---

### Scheduler

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/scheduler/jobs` | List all scheduled jobs |
| POST | `/api/scheduler/jobs` | Create a new scheduled job |
| DELETE | `/api/scheduler/jobs/{job_id}` | Delete a scheduled job |

**POST /api/scheduler/jobs**

Request body:

```json
{
  "name": "string",
  "message": "string",
  "cron_expr": "string (optional)",
  "every_seconds": "number (optional)",
  "at": "string (optional)",
  "timezone": "string (optional)",
  "channel": "string (optional)",
  "to": "string (optional)"
}
```

Provide exactly one scheduling strategy: `cron_expr`, `every_seconds`, or `at`.

---

### Config

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/config` | Get full configuration (sensitive values masked) |
| GET | `/api/config/yaml` | Get full configuration as YAML string (sensitive values masked) |
| POST | `/api/config/validate` | Validate a YAML configuration string |
| PATCH | `/api/config` | Update multiple configuration sections in a single call |
| PUT | `/api/config/{section}` | Update a single configuration section |
| POST | `/api/config/restart` | Restart all services |

**GET /api/config/yaml**

Returns the full configuration as a YAML string with sensitive values masked.

Response:

```json
{
  "yaml": "string"
}
```

**POST /api/config/validate**

Validates a YAML configuration string against the Config schema.

Request body:

```json
{
  "yaml": "string"
}
```

Response (valid):

```json
{
  "valid": true
}
```

Response (invalid):

```json
{
  "valid": false,
  "error": "string",
  "line": "number (optional)"
}
```

**PATCH /api/config**

Update multiple sections in a single call (one disk write).

Request body:

```json
{
  "sections": {
    "bot": { "name": "MyBot" },
    "server": { "port": 9000 }
  }
}
```

**PUT /api/config/{section}**

Valid sections: `bot`, `server`, `agents`, `image`, `web_client`, `tools`, `storage`, `cron`, `credentials`, `providers`, `advanced`.

Request body:

```json
{
  "data": {}
}
```

For the `advanced` section, the `data` field can contain a `yaml` key with the full YAML configuration string:

```json
{
  "data": {
    "yaml": "bot:\n  name: MyBot\n..."
  }
}
```

**POST /api/config/restart**

Restarts the agent loop, channels, and cron scheduler. No request body required.

---

## WebSocket

### Connection

Connect to the WebSocket endpoint with a valid JWT token as a query parameter:

```
ws://host:port/ws?token=JWT_TOKEN
```

### Events

#### Server to Client

| Event | Payload | Description |
|-------|---------|-------------|
| `chat:message` | `{ content, chat_id, task_id }` | Final AI response |
| `chat:thinking` | `{ task_id, chat_id, content }` | Agent reasoning and thinking steps |
| `chat:tool_use` | `{ task_id, chat_id, tool, description }` | Tool execution details |
| `task:created` | Task object | New task was created |
| `task:updated` | Task object | Task state changed |
| `channel:status` | `{ name, running }` | Channel connection status changed |
| `sessions:updated` | `{}` | Session list changed (reload sidebar) |

**chat:message**

```json
{
  "event": "chat:message",
  "data": {
    "content": "string",
    "chat_id": "string",
    "task_id": "string"
  }
}
```

**chat:thinking**

```json
{
  "event": "chat:thinking",
  "data": {
    "task_id": "string",
    "chat_id": "string",
    "content": "string"
  }
}
```

**chat:tool_use**

```json
{
  "event": "chat:tool_use",
  "data": {
    "task_id": "string",
    "chat_id": "string",
    "tool": "string",
    "description": "string"
  }
}
```

All `chat:*` events include `chat_id` so the frontend can filter messages by session. Only messages matching the active session should be displayed — others are silently ignored until the user switches to that session.

#### Client to Server

| Event | Payload | Description |
|-------|---------|-------------|
| `chat:send` | `{ data: { message, session_id, metadata? } }` | Send a chat message |

**chat:send**

Alternative to `POST /api/chat`. Sends a message through the WebSocket connection.

```json
{
  "event": "chat:send",
  "data": {
    "message": "string",
    "session_id": "string (optional)",
    "metadata": {}
  }
}
```

Files in this skill

  • README.md714 B
  • skill.md15.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.