FluxyChat

How-to Guides

Authentication (JWT)

API keys, member JWTs, roles, token refresh, and WebSocket auth.

Authentication

FluxyChat uses two credential forms:

  • API key (X-Fluxy-Api-Key): server-to-server, identifies the tenant/project.
  • JWT (Authorization: Bearer …): client-to-worker/SDK — claims include sub (userId), tid (projectId), roles, exp.

Rule: keep the API key on your backend and mint JWTs for browsers and mobile clients. Never expose the API key in client bundles.

Mint a member JWT (server-side)

export FLUXY_BASE_URL="http://127.0.0.1:8787"
export FLUXY_API_KEY="fc_..."

curl -sS -X POST "$FLUXY_BASE_URL/auth/token" \
  -H "Content-Type: application/json" \
  -H "X-Fluxy-Api-Key: $FLUXY_API_KEY" \
  -d '{"userId":"alice","roles":["member"],"ttlSeconds":3600}'

Response includes token, expiresIn, and echoed claims.

Roles

RoleTypical access
memberSend/edit own messages, reactions, read receipts, inbox
moderatorMute/ban, some admin routes
adminWebhooks, projects, alert rules
ownerSensitive tenant operations

Admin routes enforce role checks per endpoint — see OpenAPI docs for each route.

Next.js Route Handler example

import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const body = await request.json().catch(() => null);
  const userId = body?.userId;
  if (!userId) return NextResponse.json({ error: "userId required" }, { status: 400 });

  const res = await fetch(`${process.env.FLUXY_BASE_URL}/auth/token`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Fluxy-Api-Key": process.env.FLUXY_API_KEY!,
    },
    body: JSON.stringify({ userId, roles: ["member"], ttlSeconds: 3600 }),
  });

  return NextResponse.json(await res.json(), { status: res.status });
}

Wire the returned JWT into FluxyRealtimeProvider or FluxyChatClient({ token }).

WebSocket auth

GET /ws/room/:roomId?token=<JWT>

Membership is enforced — 403 / close 1008 when the user is not a room member.

Token refresh

The SDK does not expose client.updateToken(). When exp passes:

  1. Mint a new JWT on your backend (POST /auth/token).
  2. Pass it via FluxyRealtimeProvider authTokenProvider or recreate FluxyChatClient with the new token.

Hosted dashboard uses /api/fluxy/connect to refresh member JWT automatically.

Common errors

SymptomCauseFix
401 invalid api keyRevoked or wrong project keyRotate key in Projects console
FluxyTokenExpiredErrorJWT exp passedMint new JWT
FluxyNotMemberErrorUser not in roomAdd membership or join room
FluxyAnonymousNotAllowedErrorRoom requires authUse member JWT

See Troubleshooting integration for copy-paste fixes.

On this page