OpenClaw Agent — API

URL-префикс: /api/v1/admin/agent/* (через admin-bff проксируется напрямую без преобразований).

Все эндпоинты требуют Authorization: Bearer <JWT>. Проверяется permission agent.use.


Чат (главный эндпоинт)

POST /api/v1/admin/agent/chat

Отправить сообщение в существующую или новую сессию. Возвращает SSE-стрим хода рассуждений + результат.

Request body:

{
  "conversation_id": "conv_01HXYZ...",
  "message": "Создай заказ на маргариту и колу на вынос для точки Арбат"
}
  • conversation_id опционален. Если нет → создаётся новая сессия.
  • message обязателен, ≤ 2000 символов.

Response — text/event-stream:

event: conversation
data: {"conversation_id": "conv_01HXYZ...", "is_new": false}

event: message_started
data: {"message_id": "msg_01ABCD...", "role": "assistant"}

event: thinking
data: {"text": "Ищу товары: маргарита, кола"}

event: tool_call_started
data: {"tool_call_id": "call_1", "name": "find_products", "arguments": {"query": "маргарита", "store_id": "store_arbat"}}

event: tool_call_completed
data: {"tool_call_id": "call_1", "status": "ok", "duration_ms": 124, "summary": "Найдено: Пицца Маргарита (590 ₽)"}

event: tool_call_started
data: {"tool_call_id": "call_2", "name": "find_products", "arguments": {"query": "кола", "store_id": "store_arbat"}}

event: tool_call_completed
data: {"tool_call_id": "call_2", "status": "ok", "summary": "Найдено: Кока-кола (260 ₽)"}

event: tool_call_started
data: {"tool_call_id": "call_3", "name": "create_order", "arguments": {"store_id": "store_arbat", "channel": "takeaway", "items": [...]}}

event: tool_call_completed
data: {"tool_call_id": "call_3", "status": "ok", "summary": "Заказ #1234 создан, сумма 850 ₽"}

event: content_delta
data: {"text": "Заказ "}

event: content_delta
data: {"text": "#1234 "}

event: content_delta
data: {"text": "создан. Пицца Маргарита, Кока-кола, сумма 850 ₽."}

event: message_completed
data: {"message_id": "msg_01ABCD...", "finish_reason": "stop", "total_duration_ms": 12450, "eval_tokens": 187}

event: done
data: {}

Event types:

EventКогда отправляетсяPayload
conversationВ начале, если новая или возобновлена{ conversation_id, is_new }
message_startedПеред первым токеном assistant-ответа{ message_id, role }
thinkingКороткие пояснения агента (генерируется в content до tool_call){ text }
tool_call_startedПеред каждым HTTP-вызовом downstream{ tool_call_id, name, arguments }
tool_call_completedПосле результата tool{ tool_call_id, status: "ok"|"error", duration_ms, summary?, error? }
content_deltaДельта текстового ответа ассистента{ text }
message_completedФинальный токен (finish_reason=stop){ message_id, finish_reason, total_duration_ms, eval_tokens }
errorЛюбая ошибка во время стрима{ code, message }
doneКонец стрима{}

Ошибки в начале (до стрима):

HTTPCodeКогда
400MESSAGE_TOO_LONGmessage > 2000
403AGENT_ACCESS_DENIEDНет agent.use
404CONVERSATION_NOT_FOUNDconversation_id не найден или чужой
409CONVERSATION_LIMIT_REACHEDВ сессии уже 20 ходов
429RATE_LIMIT_EXCEEDEDПревышен per-user limit
503LLM_HOST_UNAVAILABLELLM-провайдер недоступен

Ошибки внутри стрима:

Эмитятся через event: error с продолжением стрима до event: done. Клиент должен отобразить error-блок в UI и оставить чат активным.


Сессии

GET /api/v1/admin/agent/conversations

Список моих сессий, отсортированных по updated_at DESC.

Query:

  • limit (default 50, max 100)
  • cursor (опаковый, для пагинации)
  • status (active / closed, default — все)

Response 200:

{
  "data": [
    {
      "id": "conv_01HXYZ...",
      "title": "Создай заказ на маргариту и колу",
      "status": "active",
      "messages_count": 8,
      "created_at": "2026-05-13T10:00:00Z",
      "updated_at": "2026-05-13T10:05:42Z"
    }
  ],
  "meta": { "next_cursor": null, "total": 1 }
}

GET /api/v1/admin/agent/conversations/{id}

История одной сессии — все сообщения в порядке создания.

Response 200:

{
  "id": "conv_01HXYZ...",
  "title": "...",
  "status": "active",
  "messages": [
    {
      "id": "msg_01...",
      "role": "user",
      "content": "Создай заказ...",
      "created_at": "..."
    },
    {
      "id": "msg_02...",
      "role": "assistant",
      "content": "Заказ #1234 создан...",
      "tool_calls": [{ "id": "call_1", "name": "find_products", ... }],
      "duration_ms": 12450,
      "created_at": "..."
    },
    {
      "id": "msg_03...",
      "role": "tool",
      "tool_call_id": "call_1",
      "content": "[{\"id\": \"prd_abc\", \"name\": \"...\"}]",
      "created_at": "..."
    }
  ]
}

Ошибки:

HTTPCode
404CONVERSATION_NOT_FOUND (не существует или чужая)

DELETE /api/v1/admin/agent/conversations/{id}

Удалить сессию вместе со всеми сообщениями.

Response 204 No Content.

POST /api/v1/admin/agent/conversations/{id}/close

Закрыть сессию (status=closed). После этого /chat с этим id будет возвращать 409.

Response 204 No Content.


Health и Admin

GET /internal/agent/health

Без auth.

{
  "status": "ok",
  "llm_provider": { "reachable": true, "latency_ms": 12 },
  "database": { "reachable": true }
}

GET /internal/agent/admin/sessions/{user_id}

Service-token. Список сессий любого юзера для аудита.

Requires agent.config у вызывающего (проверяется через JWT в Authorization).


Стандартный формат ошибки

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Превышен лимит запросов. Подожди немного.",
    "details": { "retry_after_sec": 38 }
  }
}

Ссылки