PromptFloe Developer Docs
Client SDKs

Sessions

Short-lived session tokens for browser-side calls. Your server mints a token scoped to a single end-user, the browser uses it to talk to PromptFloe directly without exposing your API key.

#Why sessions?

Live API keys (pf_live_...) must never reach the browser — anyone who reads them can run up your bill. Sessions solve this with a two-step flow:

  1. Your server proxies an "issue session" call using your API key.
  2. The server returns a short-lived session token to the browser.
  3. The browser uses the session token directly with the SDK.

Sessions are scoped to a single endUserId, expire in 60 minutes, and inherit a subset of your key's scopes.

#Server: mint a session

1

Use your live API key on the server

// app/api/promptfloe/session/route.ts
import { PromptFloe } from '@promptfloe/sdk';

const server = new PromptFloe({ apiKey: process.env.PROMPTFLOE_API_KEY });

export async function POST(req: Request) {
  const { userId } = await getCurrentUser(req);

  const session = await server.sessions.issue({
    endUserId: userId,
    scopes: ['build', 'read'],
    ttlMinutes: 30,
  });

  return Response.json({ token: session.token, expiresAt: session.expiresAt });
}
2

Browser: use the token

import { PromptFloe } from '@promptfloe/sdk';

const { token } = await fetch('/api/promptfloe/session', { method: 'POST' })
  .then(r => r.json());

const client = new PromptFloe({ apiKey: token });   // session token

const stream = client.apps.generateStream({
  prompt: 'A landing page for ' + product,
});

for await (const ev of stream) {
  if (ev.type === 'file')  setProgress(ev.path);
  if (ev.type === 'ready') setPreview(ev.previewUrl);
}

#Session scopes

A session can have at most the scopes of the parent API key. We recommend issuing the minimum subset:

  • read + build for "user generates apps in browser".
  • read only for "user views their existing apps".
  • read + build + deploy for the full lifecycle.

#Quota attribution

Calls made with a session token still count against your workspace's daily quota — but the run is tagged with the endUserId so you can break down usage per end-user in the dashboard.

#Rotation

Sessions expire automatically; the SDK refreshes them by hitting your /api/.../session endpoint on 401s if you provide a refreshFn:

const client = new PromptFloe({
  apiKey: token,
  refreshFn: async () => {
    const { token } = await fetch('/api/promptfloe/session', { method: 'POST' })
      .then(r => r.json());
    return token;
  },
});

#Where to go next

PromptFloe developer docs