# HTTP channel

A synchronous request/reply endpoint for custom integrations: a caller `POST`s a
message and gets the agent's reply in the same response.

## Configuration

Channels → **New channel** → Kind = **http**.

| Field                       | What it is                                                               |
| --------------------------- | ------------------------------------------------------------------------ |
| **Default agent**           | Agent that answers (and the concierge for command routes).               |
| **Identity**                | A short label used **in the URL**, e.g. `support`. Unique per workspace. |
| **API secret** (required)   | Callers must present it. Supports `{{ variables }}`. Requests are **rejected** while this is unset, unless the channel is marked public below. |
| **Public endpoint**         | Opt out of the secret entirely — for callers that can't hold one, like a browser widget. Anyone with the URL can then run the agent, so pair it with a rate limit. |
| **Command routes / Guards** | Optional — see the [common docs](./README.md).                           |

Save the channel, then open it and copy the URL from the **Endpoint** panel.

## Endpoint

```
POST /messages/<workspaceId>/<identity>
Content-Type: application/json

{ "message": "Hi there", "session": "user-123", "sender": "Alice" }
```

```json
→ 200 { "reply": "Hello! How can I help?", "session": "user-123" }
```

- `session` is the **thread key** — history is kept per session, so reuse it for a conversation.
- `sender` is optional; it's shown to the agent and used for the sender allowlist guard.
- Send the channel's **API secret** as either header:
  - `Authorization: Bearer <secret>`
  - `X-Api-Key: <secret>`

(There's a legacy `POST /messages/<identity>` that resolves to the default workspace — prefer the workspace-scoped URL above.)

## Example

```bash
curl -X POST 'https://api.example.com/messages/<workspaceId>/support' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <secret>' \
  -d '{ "message": "What are your hours?", "session": "web-42" }'
```

## Notes

- The call blocks until the agent finishes (including MCP tool calls), so expect multi-second responses. Upstream LLM/MCP failures surface as a `502`.
- Errors: `404` unknown channel, `401` bad/missing secret **or a channel with neither a secret nor the public flag**, `429` rate-limited, `413` message too long, `403` sender not allowed.
- Authentication is skipped only when **Public endpoint** is ticked. Leaving the secret blank without ticking it is treated as a misconfiguration and rejected — an endpoint shouldn't become public by accident.
- Whatever you choose, set a **rate limit** under Guards: `rateLimitPerMin` defaults to `0`, meaning unlimited. A public channel with no limit logs a warning on first use.
