Getting started

Connect Blazing Agents to your app

Add a chat endpoint to your backend that checks who the user is, streams the answer, and remembers each conversation.

Add one chat endpoint to your backend. It checks who the user is, sends their message to your agent, and streams the answer back. Blazing Agents keeps the conversation history, so your endpoint only has to remember which user owns which conversation.

Before you begin

Finish Run your first agent and keep the same project folder and terminal. Set the agent ID it printed, and a demo token that stands in for your own sign-in:

export BLAZING_AGENTS_AGENT_ID="ag_..."
export DEMO_USER_TOKEN="demo-token"

Keep credentials on the backend

Your browser or mobile app talks only to your backend. It never receives the Blazing Agents API key.

Put your backend between users and Blazing Agents

Install a small web framework for the endpoint:

npm install hono @hono/node-server

Your backend does three things on every request: it signs the user in, checks that they own the conversation they ask for, and calls Blazing Agents with your API key.

Add a chat endpoint

Save this as server.ts or server.py. The users and owners dictionaries stand in for your sign-in and your database.

server.ts
import { serve } from "@hono/node-server";
import { BlazingAgents, createChatRelay } from "@blazingagents/sdk";
import { Hono } from "hono";

const client = new BlazingAgents({
  apiKey: process.env.BLAZING_AGENTS_API_KEY!,
});

// Replace these with your own sign-in check and database.
const users = new Map([[process.env.DEMO_USER_TOKEN!, "user-1"]]);
const owners = new Map<string, string>();

const relayChat = createChatRelay({
  client,
  async resolveContext(request) {
    const token = request.headers.get("authorization")?.replace("Bearer ", "");
    const userId = token ? users.get(token) : undefined;
    return userId
      ? { agentId: process.env.BLAZING_AGENTS_AGENT_ID!, userId }
      : null;
  },
  sessions: {
    async ownerOf(sessionId) {
      return owners.get(sessionId);
    },
    async recordOwner(sessionId, userId) {
      owners.set(sessionId, userId);
    },
  },
});

const app = new Hono();
app.post("/api/chat", (c) => relayChat(c.req.raw));
serve({ fetch: app.fetch, port: 8787 });

Start it with node server.ts or uvicorn server:app --port 8787.

Verify the integration

In a second terminal, export DEMO_USER_TOKEN again and ask the agent to remember something:

curl -i -N http://localhost:8787/api/chat \
  -H "authorization: Bearer $DEMO_USER_TOKEN" \
  -H "content-type: application/json" \
  -d '{"message":{"id":"m1","role":"user","parts":[{"type":"text","text":"Remember the word cobalt."}]}}'

The answer streams in as data: {...} lines. Among the response headers is a location header that ends in the new ss_... session ID. Send it back with a follow-up question:

curl -N http://localhost:8787/api/chat \
  -H "authorization: Bearer $DEMO_USER_TOKEN" \
  -H "content-type: application/json" \
  -d '{"sessionId":"ss_...","message":{"id":"m2","role":"user","parts":[{"type":"text","text":"Which word did I ask you to remember?"}]}}'

The agent answers "cobalt", because Blazing Agents kept the first exchange. Leave out the authorization header and you get 401. Send a session ID the user does not own and you get 403.

What happened

The first request has no sessionId, so Blazing Agents starts a new session and returns its ID before the answer finishes streaming. Your endpoint records the owner right away, then relays the stream. Later requests send the sessionId, your endpoint checks the owner, and the agent sees the whole conversation. Your frontend sends only the newest message each time.

In TypeScript, createChatRelay does this for you. It also passes the request's abort signal along, so a user who closes the tab stops the turn. The Python endpoint does the same steps by hand with one client.chat() call: it passes session_id only when the request has one, and stream.session_id holds the ID either way.

The userId you pass labels usage and resources per end user for reporting. It does not grant access. Your ownership check is what keeps one user out of another user's conversation.

Production notes

  • Replace the demo token with your real sign-in, and the owners map with a database table.
  • Keep the session ID even when the first turn fails or the user stops it. The conversation exists; it is empty until a turn succeeds.
  • Streams must reach the browser unbuffered. The response already sets Cache-Control: no-cache; make sure every proxy in front of your backend passes the stream through as it arrives.

Next

On this page