Create Bot
Create a bot desired-state record and enqueue reconcile notification. Per-bot resource overrides are available on every plan; the plan's ``resource_maximums`` still bound how high each dimension may go. Optional ``credentials`` and ``tool_domain_settings`` are applied in the same transaction, before the bot is first provisioned, under the same rules as ``PUT …/credentials`` and ``PUT …/tool-domain-settings/{domain}``; any invalid entry fails the whole create. Sending settings without ``bot:tool_domain_settings.update`` is a 403.
Authorization
BearerAuth Botyard API key — see /docs/authentication.
In: header
Path Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Request to create a bot from guided form fields.
Response Body
application/json
curl -X POST "https://example.com/v1/orgs/string/bots" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "config": {} }'{
"id": "string",
"slug": "string",
"org_id": "string",
"cluster_id": "string",
"name": "string",
"avatar_url": "string",
"description": "string",
"namespace": "string",
"tier": "starter",
"hosting_type": "hosted",
"harness": "openclaw",
"runtime_class": "cluster_default",
"storage_class": "cluster_default",
"runtime_privilege_mode": "standard",
"durable_root_owns_home": true,
"onboarding_state": "none",
"owner_id": "string",
"access": "open",
"can_use": true,
"member_role": "owner",
"can_manage": false,
"auto_suspend_enabled": true,
"auto_suspend_effective": true,
"auto_suspend_opt_out_available": false,
"last_human_activity_at": "2019-08-24T14:15:22Z",
"suspension_reason": "manual",
"desired_state": "running",
"desired_config": {
"bot_type": "openclaw",
"agent_id": "main",
"gateway_token": "string",
"gateway": {
"mode": "local",
"bind": "lan",
"auth_mode": "token",
"control_ui_enabled": true,
"control_ui_allow_insecure_auth": true,
"allowed_origins": [],
"http_chat_completions": false,
"http_responses": false
},
"model": {
"chain": [],
"cli_allowlist": {},
"input": [
"text",
"image"
],
"context_window": 200000,
"max_tokens": 8192,
"provider_name": "botyard",
"proxy_base_url": "http://127.0.0.1:9091/v1",
"reasoning": true
},
"identity": {
"name": "string",
"theme": "AI assistant",
"emoji": "🤖",
"avatar": "string"
},
"tools": {
"exec_host": "gateway",
"exec_security": "full",
"exec_ask": "off",
"path_prepend": [],
"elevated_allow_from": {},
"allow": []
},
"browser": {
"executable_path": "/home/openclaw/bin/chromium",
"no_sandbox": true,
"headless": true
},
"skills": {
"workspace": "/home/openclaw/.openclaw/workspace",
"allow_bundled": [
"_none"
],
"watch": true
},
"commands": {
"native": "auto",
"native_skills": "auto",
"restart": true,
"owner_display": "raw",
"use_access_groups": false
},
"secrets": {
"exec_provider": {
"name": "botyard-runtime-vault",
"command": "/usr/bin/node",
"args": [
"string"
],
"timeout_ms": 10000,
"no_output_timeout_ms": 10000,
"max_output_bytes": 1048576,
"json_only": true,
"pass_env": [
"string"
],
"trusted_dirs": [
"string"
]
},
"resolution": {
"max_provider_concurrency": 4,
"max_refs_per_provider": 32,
"max_batch_bytes": 262144
}
},
"skip_bootstrap": true,
"thinking_default": "off",
"reasoning_default": "off",
"heartbeat": {
"every": "0m",
"active_hours": {
"from_time": "string",
"to_time": "string",
"timezone": "string"
},
"model": "string",
"include_reasoning": true,
"light_context": true,
"isolated_session": true,
"ack_max_chars": 0,
"prompt": "string"
},
"system_prompt_mode": "botyard",
"addons": [
{
"id": "string",
"enabled": true,
"config": {}
}
],
"claude_code": {
"slug": "string",
"key_path": "string",
"model": "sonnet-4-6",
"binary_path": "string"
},
"cli_watchdog": {
"fresh": {
"max_ms": 900000
},
"resume": {
"max_ms": 900000
}
},
"tool_search": {
"mode": "always",
"auto_threshold_percent": 10
},
"compaction": {
"reserve_tokens": 32000,
"reserve_tokens_floor": 16000,
"mid_turn_precheck": true,
"truncate_after_compaction": true,
"max_active_transcript_bytes": 8000000,
"timeout_seconds": 600
},
"session": {
"write_lock_max_hold_ms": 300000
},
"context_limits": {
"tool_result_max_chars": 16000,
"memory_get_max_chars": 1,
"memory_get_default_lines": 1,
"post_compaction_max_chars": 1
},
"context_pruning": {
"mode": "cache-ttl",
"ttl": "string",
"min_prunable_tool_chars": 32000,
"keep_last_assistants": 0
}
},
"config_generation": 0,
"observed_state": "pending",
"observed_status": {},
"reconciled_generation": 0,
"pending_config_changes": [
{
"path": "string",
"kind": "scalar",
"old_value": "string",
"new_value": "string",
"old_count": 0,
"new_count": 0
}
],
"llm_chain": {
"desired": [
{
"credential_id": "string",
"label": "string",
"provider": "string",
"api_protocol": "string",
"model_id": "string",
"ordinal": 0
}
],
"reconciled": [
{
"credential_id": "string",
"label": "string",
"provider": "string",
"api_protocol": "string",
"model_id": "string",
"ordinal": 0
}
]
},
"reconcile_error": "string",
"last_reconciled_at": "2019-08-24T14:15:22Z",
"retry_count": 0,
"auto_retry_pending": false,
"health_status": "healthy",
"last_health_check_at": "2019-08-24T14:15:22Z",
"rescue_stage": "soft",
"maintenance_restart_pending": false,
"resources": {
"resources": []
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z"
}{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string",
"error_code": "string",
"errors": [
{
"pointer": "string",
"detail": "string",
"type": "string"
}
],
"trace_id": "string"
}List Bots
List bots for an organization. Equivalent to ``POST /bots/search`` with an empty body. Prefer the search endpoint for new callers — it accepts an optional ``where`` filter DSL and is the canonical list shape going forward.
Copy Bot
Create a new bot with the same definition as an existing one. Copies what the source bot *is*: its config, managed workspace files, skills, tools, tool domain settings, credential assignments, and (by default) its Runtime Vault policy links. Does not copy what it has *lived* — memory, conversations, disk, schedules, devices, health, its email address, or its access list. The caller becomes the copy's owner. Two gates apply. ``bot:bot.create`` because this creates a bot, and so the copy is metered and capped exactly like any other creation (``MeterKey.BOT_COUNT``); and bot ownership of the *source*, because copying reads its whole definition — including which secrets it can reach.