Guides
Web API
Serve TOML agents over HTTP with Axum and SSE.
Appam ships an Axum server in appam::web with routes for agents, sessions, streaming chat, and trace viewing.
Start the Server
CLI
appam serve --agents-dir agents --host 0.0.0.0 --port 3000Library
use appam::web;
use std::path::PathBuf;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
web::serve("0.0.0.0".to_string(), 3000, PathBuf::from("agents")).await
}Route Surface
Agents
GET /api/agentsPOST /api/agentsGET /api/agents/:namePUT /api/agents/:nameDELETE /api/agents/:nameGET /api/agents/:name/configPOST /api/agents/:name/duplicatePOST /api/agents/:name/reloadGET /api/agents/:name/promptPUT /api/agents/:name/promptPOST /api/agents/:name/toolsGET /api/agents/:name/tools/:tool_namePUT /api/agents/:name/tools/:tool_nameDELETE /api/agents/:name/tools/:tool_nameGET /api/stats
Sessions
GET /api/sessionsGET /api/sessions/:session_idDELETE /api/sessions/:session_idGET /api/agents/:name/sessions
Chat
POST /api/agents/:name/chatPOST /api/sessions/:session_id/chat
Both chat endpoints accept:
{ "message": "Hello" }SSE Format
The server serializes StreamEvent values directly into the SSE data: field. It does not set a custom SSE event name; the event type is embedded in the JSON payload:
data: {"type":"session_started","session_id":"abc123"}
data: {"type":"content","content":"I can help with that."}
data: {"type":"tool_call_started","tool_name":"search","arguments":"{\"query\":\"...\"}"}
data: {"type":"done"}Error Responses
Errors are JSON:
{ "error": "Agent not found: missing-agent" }Current status codes are:
400for bad requests404for missing resources500for internal failures
Current Configuration Reality
The config structs include web and web.rate_limit sections, but web::serve(...) currently:
- takes
host,port, andagents_dirdirectly as function arguments - always enables permissive CORS
- applies a fixed governor limit of roughly 1 request per second per IP with a burst of 60
So the documented WebConfig and AppConfigBuilder fields exist, but the built-in server helper does not yet consume them.
Trace Visualizer
There is also a dedicated trace UI server:
use appam::web;
use std::path::PathBuf;
web::serve_tracing(
"127.0.0.1".to_string(),
8080,
PathBuf::from("logs"),
).await?;