Authentication and sessions

The three chat wires take the same credential. Durability is a separate choice: the OpenAI and Anthropic wires are stateless until you opt in, and AG-UI is durable from the first turn.

Authentication

All three chat wires expect a bearer credential: Authorization: Bearer <key> (the convention the OpenAI SDK sends) or x-api-key: <key> (the Anthropic SDK's header) both work on any of them. A missing or empty credential returns 401 with the matching wire's error shape ({"error": {...}} for OpenAI, {"type": "error", "error": {...}} for Anthropic, {"type": "RUN_ERROR", "message": "..."} for AG-UI).

The workflow routes are not on this bearer. On a deployed container they sit behind the container's own gate, which the control plane and Stackbone Studio satisfy for you. Under stackbone dev that gate is off, so POST /api/workflows/<name>/start answers an un-credentialed request.

Session keys

A plain chat call is stateless: you replay the full messages[] array each turn, the same as calling OpenAI or Anthropic directly. The server keeps no transcript and records each turn on its own, so a stateless conversation is never grouped into a single session.

Two optional headers change that, and each does a different job:

Header What it does Where history lives
x-stackbone-session Durable server-side session. The agent threads the conversation's history and tool state across calls, so you send only the newest user turn and the server carries the rest. Required for tool approvals. On the server
x-stackbone-conversation Grouping only. You still replay the full messages[], but the server joins the turns into one session so they show up together instead of as separate one-off runs. No durable state, no tool approvals. On the client (you replay it)

Both take any non-empty string you choose, stable for the life of one conversation. Send one, not both. A request carrying both counts as a durable session, and the server ignores x-stackbone-conversation. With neither header, each turn is an independent run and the server groups nothing.

AG-UI uses neither header. Its threadId field on the request body carries the same durable, only-send-the-newest-turn semantics as x-stackbone-session, and it is mandatory rather than opt-in. A non-empty threadId is always a durable session. Leave it empty and you get one stateless turn with no pause capability.

BUILT WITH ❤️ FROM CANADA AND SPAIN