Bamboo API Documentation
August 12, 2026 · View on GitHub
Welcome to the Bamboo AI Agent API documentation. Bamboo provides a fully self-contained AI agent backend framework with built-in HTTP/HTTPS server capabilities.
Overview
Bamboo offers RESTful API endpoints for creating and managing AI agent conversations, executing agent loops, and streaming real-time events.
Base URL
http://localhost:9562/api/v1
API Endpoints
Chat Operations
Create Chat Message
POST /api/v1/chat
Create a new chat session or add a message to an existing session.
Request Body:
{
"message": "Help me write a function",
"session_id": "optional-session-id",
"model": "claude-sonnet-4-6",
"system_prompt": "You are a helpful assistant",
"enhance_prompt": "Additional instructions",
"workspace_path": "/path/to/workspace"
}
Response: 201 Created
{
"session_id": "uuid-string",
"stream_url": "/api/v1/events/session-id",
"status": "streaming"
}
Next Steps: After creating a chat, call POST /api/v1/execute/{session_id} to start the agent.
Agent Execution
Execute Agent
POST /api/v1/execute/{session_id}
Start the agent execution loop for a session.
Path Parameters:
session_id- Session identifier from/api/v1/chat
Request Body:
{
"model": "claude-sonnet-4-6"
}
Response: 202 Accepted
{
"session_id": "session-id",
"status": "started",
"events_url": "/api/v1/events/session-id"
}
Note: The model parameter is required and must be provided in every request.
Event Streaming
Subscribe to Events (Recommended)
GET /api/v1/events/{session_id}
Subscribe to real-time agent events via Server-Sent Events (SSE).
Path Parameters:
session_id- Session identifier
Response: 200 OK (text/event-stream)
Event Format:
data: {"type":"token","content":"Hello"}
data: {"type":"tool_start","tool_call_id":"call_1","tool_name":"Read","arguments":{"file_path":"README.md"}}
data: {"type":"tool_complete","tool_call_id":"call_1","result":{ /* ToolResult */ }}
data: {"type":"complete","usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15}}
The type discriminant is the snake_case form of the AgentEvent variant (the enum is #[serde(tag = "type", rename_all = "snake_case")]).
Terminal Events:
complete- Agent finished successfullycancelled- Run cancelled by the usererror- Agent encountered an error
Example (JavaScript):
const eventSource = new EventSource('/api/v1/events/session-123');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data);
if (data.type === 'Complete' || data.type === 'Error') {
eventSource.close();
}
};
Other event transports. Besides the per-session
GET /api/v1/events/{session_id}feed above, there is an account-wide, resumable change feedGET /api/v1/stream(SSE) that multiplexes events across all sessions — resume with?since=<seq>or theLast-Event-IDheader. There is also a live WebSocket transport at/v2/stream(per-device token auth) which is the primary transport used by the web/desktop clients; the SSE feeds remain available for simple/curl clients.
Session Management
Copy Session
POST /api/v1/sessions/{session_id}/copy
Create an independent root session from an existing session. The copy receives a new id and preserves the complete transcript, durable configuration, permission mode, Project assignment, Workspace assignment, and attachments. Attachment URLs are rewritten to the copied session id. Durable workflow selection/activation snapshots are retained so the conversation can be reconstructed; workflow run ids, lifecycle outbox/cache data, and other transient execution, pending approval/question, child identity, schedule, placement, and run-status state are not copied. Copying a child session always produces an independent root with no parent chain.
The operation is failure-atomic: storage or attachment-copy failure leaves no target session or index entry. Concurrent requests intentionally create different copies.
Response: 201 Created with { "session": SessionSummary }, 404 Not Found when the source does not exist, or 500 Internal Server Error when the
copy could not be committed.
Delete Session
DELETE /api/v1/sessions/{session_id}
Delete a session and cancel any running execution.
Path Parameters:
session_id- Session identifier
Response: 200 OK (no body) or 404 Not Found
Side Effects:
- Session removed from storage
- Session removed from memory
- Running execution cancelled
Get Session History
GET /api/v1/sessions/{session_id}/history
Retrieve message history for a session.
Path Parameters:
session_id- Session identifier
Response: 200 OK
{
"session_id": "session-id",
"messages": []
}
Note: Currently returns empty messages array. Full implementation planned.
Execution Control
Stop Agent Execution
POST /api/v1/stop/{session_id}
Cancel a running agent execution.
Path Parameters:
session_id- Session identifier
Response: 200 OK
{
"success": true,
"message": "Agent execution stopped"
}
Behavior:
- Completes current LLM request
- Cancels pending tool executions
- Saves session state
- Updates status to
Cancelled
Interactive Questions
Get Pending Question
GET /api/v1/sessions/{session_id}/question
Check if the agent is waiting for user input.
Path Parameters:
session_id- Session identifier
Response (Pending Question): 200 OK
{
"has_pending_question": true,
"question": "Which language should I use?",
"options": ["TypeScript", "JavaScript", "Python"],
"allow_custom": false,
"tool_call_id": "call_123"
}
Response (No Question): 200 OK
{
"has_pending_question": false
}
Submit User Response
POST /api/v1/sessions/{session_id}/respond
Submit a response to a pending question from the conclusion_with_options tool.
Path Parameters:
session_id- Session identifier
Request Body:
{
"response": "TypeScript"
}
Response: 200 OK
{
"success": true,
"message": "Response recorded. Agent loop will continue.",
"response": "TypeScript"
}
Validation: If allow_custom is false, response must match one of the provided options.
Tool Execution
Execute Tool Directly
POST /api/v1/tools/execute
Execute a built-in tool without running the full agent loop.
Request Body:
{
"tool_name": "read_file",
"parameters": [
{"name": "path", "value": "/path/to/file"}
]
}
Response: 200 OK
{
"result": "{\"tool_name\":\"read_file\",\"result\":\"file contents\",\"display_preference\":\"Default\"}"
}
Available Tools:
read_file- Read file contentswrite_file- Write file contentsexecute_command- Execute shell commandlist_directory- List directory contentsfile_exists- Check if file existsget_file_info- Get file metadatagit_status- Get git repository statusgit_diff- Get git diff- And more...
Health Check
Health Check Endpoint
GET /health
Simple health check for load balancers and monitoring.
Response: 200 OK (plain text "OK")
Usage:
- Load balancer health probes
- Monitoring systems
- Kubernetes liveness/readiness probes
Typical Workflow
1. Create a Chat Session
curl -X POST http://localhost:9562/api/v1/chat \
-H "Content-Type: application/json" \
-d '{
"message": "Help me write a Rust function",
"model": "claude-sonnet-4-6"
}'
Response includes session_id and stream_url.
2. Start Agent Execution
curl -X POST http://localhost:9562/api/v1/execute/{session_id} \
-H "Content-Type: application/json" \
-d '{"model": "claude-sonnet-4-6"}'
Response includes events_url.
3. Subscribe to Events
const eventSource = new EventSource('/api/v1/events/{session_id}');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data);
if (data.type === 'Complete' || data.type === 'Error') {
eventSource.close();
}
};
4. Handle Interactive Questions (Optional)
If the agent asks a question:
# Check for pending question
curl http://localhost:9562/api/v1/sessions/{session_id}/question
# Submit response
curl -X POST http://localhost:9562/api/v1/sessions/{session_id}/respond \
-H "Content-Type: application/json" \
-d '{"response": "Use async/await"}'
5. Stop or Delete (Optional)
# Stop execution
curl -X POST http://localhost:9562/api/v1/stop/{session_id}
# Delete session
curl -X DELETE http://localhost:9562/api/v1/sessions/{session_id}
Error Handling
All endpoints return consistent error responses:
{
"error": "Error message",
"session_id": "session-id" // When applicable
}
Common HTTP Status Codes:
200 OK- Success201 Created- Resource created202 Accepted- Request accepted for processing400 Bad Request- Invalid request or missing parameters404 Not Found- Resource not found500 Internal Server Error- Server error
Event Types
AgentEvent Types
The type field is the snake_case name of the AgentEvent variant
(crates/core/bamboo-agent-core/src/agent/events.rs). The most common
streaming variants:
type | Description | Fields |
|---|---|---|
token | Assistant text token | content |
reasoning_token | Reasoning/thinking token | content |
tool_token | Live output from a running tool | tool_call_id, content |
tool_start | Tool execution started | tool_call_id, tool_name, arguments |
tool_complete | Tool finished successfully | tool_call_id, result |
tool_error | Tool failed | tool_call_id, error |
token_budget_updated | Token usage / budget update | usage |
complete | Execution finished | usage |
cancelled | Run cancelled by the user | message |
error | Execution failed | message |
The enum also carries session-, task-, plan-, and sub-agent-lifecycle variants
(e.g. tool_lifecycle, need_clarification, task_list_updated,
sub_agent_started, plan_mode_entered, message_appended); consult
events.rs for the exhaustive list and exact field shapes.
Configuration
Bamboo can be configured via command-line flags or environment variables:
bamboo serve --port 9562 --data-dir ~/.local/share/bamboo
Environment Variables:
BAMBOO_PORT- Server port (default: 9562)BAMBOO_DATA_DIR- Data directoryBAMBOO_BIND- Bind address (default: 127.0.0.1)BAMBOO_WORKSPACE_ROOT- Root directory for session workspaces that have no explicit path (default:<data-dir>/workspaces). A session with no configured/explicit workspace gets<workspace-root>/<session-id>instead of the server process's working directory.BAMBOO_WORKSPACE_CONFINE- Set to1/trueto require every explicit workspace path to be canonicalized and confined underBAMBOO_WORKSPACE_ROOT(escapes via.., a symlink, or an absolute path elsewhere are relocated under the root instead of honored as-is). Off by default for local single-user use, where pointing bamboo at an existing project directory anywhere on disk must keep working; implicitly enabled whenBAMBOO_WORKSPACE_ROOTis set explicitly. Intended for orchestrated / multi-tenant deployments that want "one folder = one tenant's entire state".
Runtime Config Patching (POST /v1/bamboo/config)
The live config.json (providers, subagents, notifications, MCP servers,
bamboo-connect platforms, ...) is updated with a partial JSON PATCH — you
only send the fields you want to change. Two rules:
-
An omitted key leaves the existing value unchanged. This is unconditional back-compat: a patch that doesn't mention a field never touches it.
-
An explicit JSON
nulldeletes that field, opt-in per value (RFC 7386 JSON Merge Patch semantics). What "deleted" means depends on what's there:- an optional field (e.g.
subagents.claude_code_binary) → cleared back to unset. - a whole object subtree (e.g.
notifications: null) → reset to defaults. - one entry of a dynamic map (e.g.
provider_instances: {"<id>": null},mcpServers: {"<name>": null}) → that one entry removed, siblings untouched. - a whole array (e.g.
connect.platforms: null) → emptied. Anullinside an array element is never a delete marker — arrays are always replaced wholesale, not merged element-by-element.
Secret fields (
api_key,token,device_key,app_secret) treatnullas an explicit clear, equivalent to sending""— both are distinct from a masked placeholder (****...****, which means "keep the existing secret").Choose your blast radius by choosing which level you null out: nulling a single leaf (
providers.openai.api_key: null) clears just that field; nulling an enclosing object (providers.openai: null) wipes the whole provider's config. - an optional field (e.g.
See bamboo_config::patch::deep_merge_json's doc comment for the full
semantics table and the precedence rules against masked-placeholder
resolution.
Architecture
Bamboo follows a session-based architecture with unified server implementation:
- Session: Contains conversation history and state
- Agent Loop: Processes messages and executes tools
- LLM Provider: Communicates with AI model APIs (OpenAI, Anthropic, Gemini, Copilot)
- Tool Executor: Runs built-in tools (read, write, execute, etc.)
- Event Broadcaster: Streams real-time events via Server-Sent Events
- Unified Server: Single HTTP server with explicit routing (~120 routes)
Server Architecture
bamboo-servercrate: Unified HTTP server with explicit routing- Explicit routing: All routes registered in
crates/bamboo-server/src/routes/ - Direct provider access: No HTTP callbacks to self (eliminates proxy pattern)
- Handler organization (
crates/bamboo-server/src/handlers/):- Core agent handlers in
handlers/agent/(chat, execute, events, stop, history, respond, etc.) - Provider handlers in
handlers/(openai/, anthropic/, gemini/, copilot_auth/, agent_api.rs) - Feature handlers in
handlers/(settings/, tools/, workspace/, skill/, command/)
- Core agent handlers in
License
MIT License
Support
- GitHub Issues: https://github.com/bigduu/Bamboo-agent/issues
- Documentation: https://docs.rs/bamboo-agent