> ## Documentation Index
> Fetch the complete documentation index at: https://beige.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP API

> Gateway REST API reference for external integrations

The HTTP API is also described in [Channels → Custom Integrations](/channels#custom-integrations-via-http-api).

***

The gateway exposes an HTTP API on port 7433 (configurable via `gateway.port`). This API is used by the TUI (for LLM proxying and tool execution), by plugin channels, and can be used for custom integrations.

## Base URL

```
http://127.0.0.1:7433
```

The host and port can be configured in `config.json5`:

```json5 theme={null}
{
  gateway: {
    host: "127.0.0.1",  // default
    port: 7433,          // default
  },
}
```

## Endpoints

### Health Check

```
GET /api/health
```

Returns the gateway health status.

**Response:**

```json theme={null}
{
  "status": "ok"
}
```

**Example:**

```bash theme={null}
curl http://127.0.0.1:7433/api/health
```

***

### List Agents

```
GET /api/agents
```

Returns all configured agents with their model configuration, tool/skill assignments, and pre-built context strings for the system prompt.

**Response:**

```json theme={null}
{
  "agents": [
    {
      "name": "assistant",
      "model": {
        "provider": "anthropic",
        "model": "claude-sonnet-4-6",
        "thinkingLevel": "off"
      },
      "fallbackModels": [
        { "provider": "anthropic", "model": "claude-3-5-sonnet-20241022" }
      ],
      "tools": ["git"],
      "skills": ["code-review"],
      "workspaceDir": "/home/user/projects",
      "toolContext": "## Available Tools\n\n### git\n...",
      "skillContext": "## Available Skills\n\n### code-review\n..."
    }
  ]
}
```

**Example:**

```bash theme={null}
curl http://127.0.0.1:7433/api/agents
```

***

### Get Config

```
GET /api/config
```

Returns agent configurations and provider metadata (without API keys).

**Response:**

```json theme={null}
{
  "agents": {
    "assistant": {
      "model": {
        "provider": "anthropic",
        "model": "claude-sonnet-4-6"
      },
      "fallbackModels": [],
      "tools": ["git"],
      "skills": [],
      "workspaceDir": "/home/user/projects"
    }
  },
  "llm": {
    "providers": {
      "anthropic": {
        "baseUrl": null,
        "api": null
      }
    }
  }
}
```

**Example:**

```bash theme={null}
curl http://127.0.0.1:7433/api/config
```

***

### List Agent Models

```
GET /api/agents/:name/models
```

Returns model metadata for the agent's allowed models (primary + fallbacks). The TUI uses this to set up proxy model registrations without needing API keys.

**Parameters:**

* `:name` — Agent name (URL-encoded)

**Response:**

```json theme={null}
{
  "models": [
    {
      "id": "claude-sonnet-4-6",
      "name": "Claude Sonnet 4",
      "provider": "anthropic",
      "api": "anthropic-messages",
      "baseUrl": "https://api.anthropic.com",
      "reasoning": false,
      "input": ["text", "image"],
      "cost": { "input": 3, "output": 15, "cacheRead": 0.3, "cacheWrite": 3.75 },
      "contextWindow": 200000,
      "maxTokens": 16384,
      "thinkingLevel": "off"
    }
  ]
}
```

**Example:**

```bash theme={null}
curl http://127.0.0.1:7433/api/agents/assistant/models
```

***

### Execute Tool

```
POST /api/agents/:name/exec
```

Execute a core tool (`read`, `write`, `patch`, `exec`) in the agent's sandbox.

**Parameters:**

* `:name` — Agent name (URL-encoded)

**Request Body:**

```json theme={null}
{
  "tool": "read|write|patch|exec",
  "params": {
    // Tool-specific parameters
  },
  "sessionKey": "optional-session-key"
}
```

The optional `sessionKey` is used to derive the channel and session context injected as environment variables into the sandbox (`BEIGE_AGENT_NAME`, `BEIGE_CHANNEL`, `BEIGE_SESSION_KEY`). If omitted, defaults to `tui:<agentName>:default`.

**Response:**

```json theme={null}
{
  "content": [
    {
      "type": "text",
      "text": "Tool output..."
    }
  ],
  "isError": false
}
```

**Tool Parameters:**

| Tool    | Parameters                                              |
| ------- | ------------------------------------------------------- |
| `read`  | `path` (string), `offset?` (number), `limit?` (number)  |
| `write` | `path` (string), `content` (string)                     |
| `patch` | `path` (string), `oldText` (string), `newText` (string) |
| `exec`  | `command` (string), `timeout?` (number, seconds)        |

**Examples:**

```bash theme={null}
# Read a file
curl -X POST http://127.0.0.1:7433/api/agents/assistant/exec \
  -H "Content-Type: application/json" \
  -d '{"tool": "read", "params": {"path": "/workspace/file.txt"}}'

# Write a file
curl -X POST http://127.0.0.1:7433/api/agents/assistant/exec \
  -H "Content-Type: application/json" \
  -d '{"tool": "write", "params": {"path": "/workspace/output.txt", "content": "Hello, world!"}}'

# Execute a command
curl -X POST http://127.0.0.1:7433/api/agents/assistant/exec \
  -H "Content-Type: application/json" \
  -d '{"tool": "exec", "params": {"command": "ls -la /workspace"}}'
```

***

### Send Prompt

```
POST /api/agents/:name/prompt
```

Send a message to an agent and get the full response (non-streaming). The agent session is managed server-side by the gateway's AgentManager, including fallback model handling and hook execution.

**Parameters:**

* `:name` — Agent name (URL-encoded)

**Request Body:**

```json theme={null}
{
  "message": "Your message to the agent",
  "sessionKey": "optional-session-key"
}
```

If `sessionKey` is omitted, a default session key is used (`api:<agentName>:default`).

**Response:**

```json theme={null}
{
  "response": "Agent's response text..."
}
```

**Example:**

```bash theme={null}
curl -X POST http://127.0.0.1:7433/api/agents/assistant/prompt \
  -H "Content-Type: application/json" \
  -d '{"message": "List files in my workspace"}'
```

***

### Stream LLM Response (LLM Proxy)

```
POST /api/chat/stream
```

Proxy an LLM call through the gateway. The gateway resolves API keys server-side, executes prePrompt/postResponse hooks, applies fallback model logic on rate-limit errors, and audit-logs the call. Responses are streamed back as newline-delimited JSON (`AssistantMessageEvent` objects from the pi SDK).

This is the endpoint the TUI uses for all LLM calls — it never needs API keys locally.

**Request Body:**

```json theme={null}
{
  "provider": "anthropic",
  "modelId": "claude-sonnet-4-6",
  "context": { /* pi SDK Context object (messages array + system prompt) */ },
  "options": {
    "reasoning": true,
    "maxTokens": 8192,
    "temperature": 0.7
  },
  "agentName": "assistant",
  "sessionKey": "tui:assistant:default"
}
```

**Response:** Newline-delimited JSON stream (`application/x-ndjson`).

Each line is a JSON object — standard pi `AssistantMessageEvent` types plus two gateway-specific event types:

| Event type       | Description                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------ |
| `text_delta`     | Streaming text chunk                                                                       |
| `done`           | Stream complete, includes full message with usage stats                                    |
| `error`          | LLM error (includes error message)                                                         |
| `blocked`        | Gateway prePrompt hook blocked the message (includes `reason`)                             |
| `model_fallback` | Gateway switched to a fallback model due to rate limiting (includes `provider`, `modelId`) |

**Example:**

```bash theme={null}
curl -X POST http://127.0.0.1:7433/api/chat/stream \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "anthropic",
    "modelId": "claude-sonnet-4-6",
    "context": {"messages": [{"role": "user", "content": "Hello!"}]},
    "agentName": "assistant"
  }'
```

***

### List Sessions

```
GET /api/agents/:name/sessions
```

List saved sessions for an agent.

**Parameters:**

* `:name` — Agent name (URL-encoded)

**Response:**

```json theme={null}
{
  "sessions": [
    {
      "id": "telegram:123456:789",
      "file": "/Users/you/.beige/sessions/assistant/abc123.jsonl",
      "createdAt": "2025-03-06T12:00:00.000Z",
      "updatedAt": "2025-03-06T14:30:00.000Z"
    }
  ]
}
```

**Example:**

```bash theme={null}
curl http://127.0.0.1:7433/api/agents/assistant/sessions
```

***

### Restart Gateway

```
POST /api/gateway/restart
```

Trigger a graceful in-place restart of the gateway:

1. Drain all in-flight LLM/tool calls (including proxied TUI streams)
2. Tear down sandboxes, sockets, API, and channels
3. Reload config from disk
4. Restart everything fresh

**Response:**

```json theme={null}
{
  "status": "restarting",
  "message": "Graceful restart initiated. Follow progress with: beige gateway logs -f"
}
```

Returns `202 Accepted` immediately; the restart happens asynchronously.

**Example:**

```bash theme={null}
curl -X POST http://127.0.0.1:7433/api/gateway/restart
```

***

### Hook Endpoints

These endpoints execute plugin hooks. They are used by the TUI for session lifecycle events and are available for custom integrations. The prePrompt and postResponse hooks for TUI LLM calls are now executed server-side inside the `/api/chat/stream` endpoint automatically.

#### Run prePrompt Hooks

```
POST /api/agents/:name/hooks/pre-prompt
```

**Request Body:**

```json theme={null}
{
  "message": "User's message",
  "sessionKey": "tui:assistant:default",
  "channel": "tui"
}
```

**Response:**

```json theme={null}
{
  "message": "Possibly transformed message",
  "block": false,
  "reason": null
}
```

#### Run postResponse Hooks

```
POST /api/agents/:name/hooks/post-response
```

**Request Body:**

```json theme={null}
{
  "response": "LLM's response text",
  "sessionKey": "tui:assistant:default",
  "channel": "tui"
}
```

**Response:**

```json theme={null}
{
  "response": "Possibly transformed response",
  "block": false
}
```

#### Fire sessionCreated Hook

```
POST /api/agents/:name/hooks/session-created
```

**Request Body:**

```json theme={null}
{
  "sessionKey": "tui:assistant:default",
  "channel": "tui"
}
```

**Response:** `{ "ok": true }`

#### Fire sessionDisposed Hook

```
POST /api/agents/:name/hooks/session-disposed
```

**Request Body:**

```json theme={null}
{
  "sessionKey": "tui:assistant:default",
  "channel": "tui"
}
```

**Response:** `{ "ok": true }`

***

## Error Responses

All endpoints return errors in a consistent format:

```json theme={null}
{
  "error": "Error message describing what went wrong"
}
```

Common HTTP status codes:

| Code | Meaning                                  |
| ---- | ---------------------------------------- |
| 200  | Success                                  |
| 202  | Accepted (async operation started)       |
| 400  | Bad request (missing/invalid parameters) |
| 404  | Not found (unknown agent, etc.)          |
| 500  | Internal server error                    |

***

## Authentication

The HTTP API currently has **no authentication**. It binds to `127.0.0.1` by default and is intended for local use only.

If you expose the API to a network, you are responsible for adding authentication (e.g., via a reverse proxy with basic auth, or by modifying the gateway code).

***

## Rate Limiting

There is no built-in rate limiting on the HTTP API itself. The gateway tracks per-provider rate limits internally and applies fallback logic automatically (see [LLM Providers → Model Fallback](/agents/providers#model-fallback)).

***

## Using the API from Code

### JavaScript/TypeScript

```typescript theme={null}
const GATEWAY_URL = "http://127.0.0.1:7433";

async function execTool(agent: string, tool: string, params: Record<string, any>) {
  const res = await fetch(`${GATEWAY_URL}/api/agents/${agent}/exec`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ tool, params }),
  });
  return res.json();
}

// Example usage
const result = await execTool("assistant", "exec", {
  command: "ls -la /workspace",
});
console.log(result);
```

### Python

```python theme={null}
import requests

GATEWAY_URL = "http://127.0.0.1:7433"

def exec_tool(agent: str, tool: str, params: dict):
    response = requests.post(
        f"{GATEWAY_URL}/api/agents/{agent}/exec",
        json={"tool": tool, "params": params},
    )
    return response.json()

# Example usage
result = exec_tool("assistant", "exec", {"command": "ls -la /workspace"})
print(result)
```
