Skip to content

API Reference

All MateClaw REST endpoints use the /api/v1/ prefix. Responses follow a standard envelope:

json
{
  "code": 200,
  "message": "success",
  "data": { }
}

Authentication is required for all endpoints except /api/v1/auth/login. Include the JWT token in every request:

Authorization: Bearer <token>

Authentication

Login

POST /api/v1/auth/login

Request Body:

json
{
  "username": "admin",
  "password": "admin123"
}

Response:

json
{
  "code": 200,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiJ9...",
    "tokenType": "Bearer",
    "expiresIn": 86400
  }
}

Example:

bash
curl -X POST http://localhost:18088/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}'

Chat

Send Message

POST /api/v1/chat/{agentId}/message

Path Parameters:

ParameterTypeDescription
agentIdLongAgent ID to chat with

Request Body:

json
{
  "content": "What is the current time in Tokyo?",
  "conversationId": "conv-abc123"
}

If conversationId is omitted, a new conversation is created.

Response:

json
{
  "code": 200,
  "data": {
    "messageId": "msg-xyz789",
    "conversationId": "conv-abc123",
    "content": "The current time in Tokyo is 2025-03-15 23:30:22 JST.",
    "role": "assistant"
  }
}

Example:

bash
curl -X POST http://localhost:18088/api/v1/chat/1/message \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"Hello, what can you do?"}'

SSE Stream

GET /api/v1/chat/{agentId}/stream?conversationId={conversationId}

Returns a Server-Sent Events stream. See Chat & Messaging for event types and format.

Example:

bash
curl -N http://localhost:18088/api/v1/chat/1/stream?conversationId=conv-abc123 \
  -H "Authorization: Bearer YOUR_TOKEN"

Agents

List Agents

GET /api/v1/agents

Query Parameters:

ParameterTypeDefaultDescription
pageInteger1Page number
sizeInteger20Page size

Response:

json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "name": "Default Agent",
        "agentType": "react",
        "systemPrompt": "You are a helpful assistant...",
        "modelConfigId": 1,
        "tools": "DateTimeTool,WebSearchTool",
        "enabled": true,
        "createTime": "2025-01-01T00:00:00"
      }
    ],
    "total": 1,
    "current": 1,
    "size": 20
  }
}

Get Agent

GET /api/v1/agents/{id}

Create Agent

POST /api/v1/agents

Request Body:

json
{
  "name": "Research Assistant",
  "agentType": "react",
  "systemPrompt": "You are a research assistant. Use web search to find information.",
  "modelConfigId": 1,
  "tools": "WebSearchTool,DateTimeTool,ReadFileTool"
}

Example:

bash
curl -X POST http://localhost:18088/api/v1/agents \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Research Bot",
    "agentType": "react",
    "systemPrompt": "You help users research topics.",
    "modelConfigId": 1,
    "tools": "WebSearchTool,DateTimeTool"
  }'

Update Agent

PUT /api/v1/agents/{id}

Request Body: Same fields as Create (partial updates supported).

Delete Agent

DELETE /api/v1/agents/{id}

Soft-deletes the agent (sets deleted = 1).


Conversations

List Conversations

GET /api/v1/conversations

Query Parameters:

ParameterTypeDefaultDescription
pageInteger1Page number
sizeInteger20Page size
agentIdLong-Filter by agent

Get Conversation Messages

GET /api/v1/conversations/{conversationId}/messages

Response:

json
{
  "code": 200,
  "data": [
    {
      "id": "msg-001",
      "role": "user",
      "content": "What time is it?",
      "createTime": "2025-03-15T14:00:00"
    },
    {
      "id": "msg-002",
      "role": "assistant",
      "content": "The current time is 14:00 UTC.",
      "toolCalls": [],
      "createTime": "2025-03-15T14:00:01"
    }
  ]
}

Delete Conversation

DELETE /api/v1/conversations/{conversationId}

Tools

List Tools

GET /api/v1/tools

Response:

json
{
  "code": 200,
  "data": [
    {
      "id": 1,
      "name": "DateTimeTool",
      "description": "Get the current date and time",
      "type": "builtin",
      "dangerous": false,
      "enabled": true
    },
    {
      "id": 2,
      "name": "ShellExecuteTool",
      "description": "Execute shell commands",
      "type": "builtin",
      "dangerous": true,
      "enabled": true
    }
  ]
}

Update Tool

PUT /api/v1/tools/{id}

Request Body:

json
{
  "enabled": false
}

Skills

List Skills

GET /api/v1/skills

Query Parameters:

ParameterTypeDefaultDescription
pageInteger1Page number
sizeInteger20Page size
typeString-Filter by type: builtin, custom, mcp
tagString-Filter by tag

Get Skill

GET /api/v1/skills/{id}

Create Skill

POST /api/v1/skills

Request Body:

json
{
  "name": "code-reviewer",
  "title": "Code Reviewer",
  "description": "Review code for bugs and improvements",
  "type": "custom",
  "content": "---\nname: code-reviewer\ntitle: Code Reviewer\ndescription: Review code\nversion: 1.0.0\ntype: custom\ntools:\n  - ReadFileTool\n---\n\n# Code Reviewer\n\nReview the provided code...",
  "tags": ["development", "review"]
}

Example:

bash
curl -X POST http://localhost:18088/api/v1/skills \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "summarizer",
    "title": "Text Summarizer",
    "description": "Summarize long text into key points",
    "type": "custom",
    "content": "---\nname: summarizer\ntitle: Text Summarizer\nversion: 1.0.0\ntype: custom\n---\n\nSummarize the given text into bullet points.",
    "tags": ["text", "summary"]
  }'

Update Skill

PUT /api/v1/skills/{id}

Delete Skill

DELETE /api/v1/skills/{id}

Model Providers

List Providers

GET /api/v1/model-providers

Response:

json
{
  "code": 200,
  "data": [
    {
      "id": 1,
      "name": "dashscope",
      "displayName": "DashScope",
      "baseUrl": "https://dashscope.aliyuncs.com",
      "apiKey": "sk-****",
      "enabled": true
    }
  ]
}

Create Provider

POST /api/v1/model-providers

Request Body:

json
{
  "name": "openai",
  "displayName": "OpenAI",
  "baseUrl": "https://api.openai.com",
  "apiKey": "sk-your-openai-key",
  "enabled": true
}

Update Provider

PUT /api/v1/model-providers/{id}

Delete Provider

DELETE /api/v1/model-providers/{id}

Model Configurations

List Model Configs

GET /api/v1/model-configs

Query Parameters:

ParameterTypeDescription
providerIdLongFilter by provider

Create Model Config

POST /api/v1/model-configs

Request Body:

json
{
  "providerId": 1,
  "modelName": "qwen-plus",
  "displayName": "Qwen Plus",
  "temperature": 0.7,
  "maxTokens": 4096,
  "topP": 0.9,
  "enabled": true
}

Update Model Config

PUT /api/v1/model-configs/{id}

Delete Model Config

DELETE /api/v1/model-configs/{id}

Channels

List Channels

GET /api/v1/channels

Create Channel

POST /api/v1/channels

Request Body:

json
{
  "name": "My Telegram Bot",
  "type": "telegram",
  "config": {
    "botToken": "123456:ABC-DEF"
  },
  "agentId": 1,
  "enabled": true
}

Update Channel

PUT /api/v1/channels/{id}

Delete Channel

DELETE /api/v1/channels/{id}

Channel Webhook Callbacks

ChannelCallback URL
DingTalkPOST /api/v1/channels/dingtalk/callback
FeishuPOST /api/v1/channels/feishu/callback
WeChat WorkPOST /api/v1/channels/wechat-work/callback
TelegramPOST /api/v1/channels/telegram/callback
DiscordPOST /api/v1/channels/discord/callback

System Settings

Get All Settings

GET /api/v1/settings

Update a Setting

PUT /api/v1/settings/{key}

Request Body:

json
{
  "value": "new-value"
}

Example:

bash
curl -X PUT http://localhost:18088/api/v1/settings/default_agent_id \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": "2"}'

Users

Get Current User

GET /api/v1/users/me

Update Profile

PUT /api/v1/users/me

Request Body:

json
{
  "nickname": "John",
  "avatar": "https://example.com/avatar.jpg"
}

Change Password

PUT /api/v1/users/me/password

Request Body:

json
{
  "oldPassword": "admin123",
  "newPassword": "new-secure-password"
}

Error Responses

All error responses follow the same format:

json
{
  "code": 400,
  "message": "Validation failed: name is required"
}

Common Status Codes

CodeMeaning
200Success
400Bad request -- validation failed or missing parameters
401Unauthorized -- token missing, expired, or invalid
403Forbidden -- insufficient permissions
404Not found -- resource does not exist
500Internal server error

Pagination

List endpoints return paginated results:

json
{
  "code": 200,
  "data": {
    "records": [ ],
    "total": 42,
    "current": 1,
    "size": 20,
    "pages": 3
  }
}
FieldDescription
recordsArray of items on the current page
totalTotal number of items
currentCurrent page number (1-based)
sizeItems per page
pagesTotal number of pages

Next Steps