Skip to main content

1. Add Streamstraight to your server

Instead of returning the LLM response stream to your client via an HTTP Server-sent Events Response, we’ll forward it to Streamstraight instead. First, install our server SDK for your language. If your SDK isn’t listed here, drop us a line.
npm install --save @streamstraight/server
Next, navigate to the Streamstraight dashboard and create an API key. Create a .env entry for the API key you generate in the Streamstraight dashboard. In production, make sure to add this API key to your server secrets.
STREAMSTRAIGHT_API_KEY=YOUR_KEY_HERE

Pass your stream to Streamstraight

Next, ensure you have a unique streamId for the AI response. We recommend using a combination of the AI chat’s chatId and messageId to create a unique identifier. We’ll then pass the stream to Streamstraight’s SDK.
import { streamstraightServer } from "@streamstraight/server";
import OpenAI from "openai";

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const ssServer = await streamstraightServer(
  { apiKey: process.env.STREAMSTRAIGHT_API_KEY },
  { streamId: "a-unique-stream-id" },
);

// We use the OpenAI SDK here as an example, but you can use any
// LLM provider that supports streaming
const stream = await openai.responses.stream({ ... });

// llmStream can be any ReadableStream or AsyncIterable
await ssServer.stream(llmStream);
Streamstraight will now consume and forward the LLM stream to your client.
Depending on your architecture, the LLM stream may block your HTTP response. If you would like to continue streaming without blocking your HTTP response, follow the instructions in the advanced usage guide.

Add a route for fetching your JWT token

Streamstraight requires your frontend client to securely connect via a short-lived JWT token. Add a route to your server that fetches this token using our SDK.
import { fetchClientToken } from "@streamstraight/server";

// In the /api/streamstraight-token route
export async function POST(request: Request) {
  if (request.method !== "POST") {
    return new Response("Method not allowed", { status: 405 });
  }
  // Ensure your user is authenticated

  const clientToken = await fetchClientToken({
    apiKey: process.env.STREAMSTRAIGHT_API_KEY
  });
  return { jwtToken: clientToken };
}

2: Add Streamstraight to your client

First, install the Streamstraight client SDK to your app:
npm install --save @streamstraight/client
Next, we’ll need to connect to Streamstraight from your client so that we can receive the stream. Provide the SDK with the streamId you generated on the server and a function that fetches a fresh JWT from your backend.
import { connectStreamstraightClient } from "@streamstraight/client";

// Type each chunk however you want; you're not tied
// to the OpenAI example here. Just make sure the type
// matches what you pass to Streamstraight on your server.
type ChunkType = OpenAI.Responses.ResponseStreamEvent;

async function fetchStreamstraightToken(): Promise<string> {
  const response = await fetch("/api/streamstraight-token", { method: "POST" });
  if (!response.ok) throw new Error("Failed to fetch Streamstraight token");

  const { jwtToken } = (await response.json()) as { jwtToken: string };
  return jwtToken;
}

async function processResponseStream(streamId: string) {
  const ssClient = await connectStreamstraightClient<ChunkType>(
    { fetchToken: fetchStreamstraightToken },
    { streamId },
  );

  for await (const chunk of ssClient.toAsyncIterable()) {
    // Handle each chunk as it's streamed
  }
}
If you are using the useChat abstraction from Vercel’s AI SDK, we’ve built a way to integrate directly into that abstraction! Please refer to these instructions instead.
That’s it! Your client will now reliably receive stream chunks from your server through Streamstraight.