@fluxyte/sdk
v0.4.2
Published
Official Fluxyte SDK (TypeScript) for the Fluxyte Onboarding AI API
Readme
Fluxyte SDK (TypeScript)
The official TypeScript SDK for the Fluxyte Onboarding AI API: a context-aware, documentation-grounded assistant designed for onboarding and setup flows (not generic chat).
What's New In 0.4.0
- Voice chat API via
client.voiceChat(...)for speech input. - Optional synthesized audio reply output.
- React voice chat hook support for UI integration.
Install
npm install @fluxyte/sdkRequirements
- Browser or Node.js 18+ (global
fetchavailable) - A Fluxyte API key (sent as
X-API-Key)pk_*for browser/public SDK usagesk_*for backend/server usage only
Authentication (API Key)
Treat your API key like a password. Do not commit it to source control.
Create an API key
- Sign up at
https://fluxyte.com/signup - Verify your email
- Open the
Accountmenu - Select
API Keys - Click
Create API Key - Choose key type:
pk_*(PUBLIC) for frontend/browser SDK usagesk_*(SECRET) for backend/server-only usage
- Copy your API key (shown once)
Use an API key
All integrations authenticate with an API key sent in the X-API-Key header.
- Use
pk_*keys in browser/public SDK integrations - Use
sk_*keys only in backend/server environments - For
pk_*keys, configure allowed origins to restrict frontend domains - The key controls organization access, docs scope, and analytics ownership
Environment examples
- Vite:
VITE_FLUXYTE_API_KEY=pk_... - Next.js:
NEXT_PUBLIC_FLUXYTE_API_KEY=pk_...(public key only) - Server:
FLUXYTE_API_KEY=sk_...
The SDK rejects sk_* keys in browser environments to prevent accidental exposure.
Key Management
Key Purpose
pk_*(PUBLIC): for browser/frontend SDK usage.sk_*(SECRET): for backend/server usage only.
How to get keys
- Sign in to Fluxyte dashboard.
- Go to
Account->API Keys. - Create a key and choose type:
PUBLIC (pk_*)for frontend SDK traffic.SECRET (sk_*)for backend automation or server integrations.
- Copy the key immediately (shown once).
Allowed origins (PUBLIC keys)
For pk_* keys, configure allowed origins in dashboard (for example https://app.example.com).
This limits where browser-based SDK requests are accepted from.
Rotation and revocation
- Rotate keys on a regular schedule (recommended every 60-90 days).
- Keep a short overlap window where old and new keys are both valid during rollout.
- Revoke keys immediately if exposed.
- Update environment variables and redeploy clients after rotation.
Environment examples
- Frontend:
NEXT_PUBLIC_FLUXYTE_API_KEY=pk_... - Backend:
FLUXYTE_API_KEY=sk_...
Never expose sk_* in browser bundles, client logs, or public repos.
Choose An Entrypoint
The SDK ships multiple entrypoints, all with the same API surface:
@fluxyte/sdk/react(React hooks + provider)@fluxyte/sdk/node(server-side; validatesfetchavailability)@fluxyte/sdk/vanilla(browser usage without React)@fluxyte/sdk(base exports)
Create A Client (Node / Vanilla)
import { OnboardingAIClient } from "@fluxyte/sdk/node";
const client = new OnboardingAIClient(process.env.FLUXYTE_API_KEY!);Client Options (Session Handling)
The SDK now enforces stable identity for chat/events (sessionId or context.userId).
- By default, it auto-generates and reuses
sessionIdwhen missing. - You can disable this with
autoSessionId: false.
const client = new OnboardingAIClient(process.env.FLUXYTE_API_KEY!, {
autoSessionId: true, // default
sessionStorageKey: "fluxyte_onboarding_session_id", // browser storage key
});Chat Completions (Non-Streaming)
const res = await client.chat({
message: "How do I connect my database?",
sessionId: "sess_123",
context: {
product: "analytics-dashboard",
userTarget: "admin",
stepSlug: "connect_database",
},
});
console.log(res.answerId);
console.log(res.reply);
console.log(res.confidence);
console.log(res.sources);Chat Completions (Streaming via SSE)
Streaming is useful when you want:
- live typing UX
- progressive rendering
- early access to
answerId(for feedback)
Streaming lifecycle:
meta(containsanswerId)delta(partial text; one or more)done(confidence, sources)
const stop = client.streamChat(
{
message: "What's the next step?",
sessionId: "sess_123",
context: { service: "premium-support", userTarget: "admin" },
},
(event) => {
if (event.type === "meta") console.log("Answer ID:", event.answerId);
if (event.type === "delta") process.stdout.write(event.replyDelta);
if (event.type === "done") {
console.log("\nConfidence:", event.confidence);
console.log("Sources:", event.sources);
}
},
(err) => {
// Optional: handle auth/network/server errors.
console.error("Streaming error:", err);
},
);
// stop() cancels streamingVoice Chat (Speech In + Optional Speech Out)
const voice = await client.voiceChat({
audioBase64: "BASE64_AUDIO",
mimeType: "audio/webm",
context: {
product: "analytics-dashboard",
userTarget: "admin",
},
synthesize: true,
voice: "alloy",
audioFormat: "mp3",
});
console.log(voice.transcript); // text recognized from audio
console.log(voice.reply); // AI text reply
console.log(voice.replyAudioBase64); // optional synthesized voiceContext
Context is required for chat requests. Minimum shape:
context: { product?: string; service?: string; userTarget: string }Best practices:
- Use stable
productorserviceidentifiers - Always pass
userTarget - Include
flowSlug/stepSlugwhen available - Provide at least one stable identity:
sessionIdorcontext.userId - Treat context like application state (update it as the user moves)
Identity guidance:
- Anonymous visitors: let SDK auto-manage
sessionIdor pass your own persisted ID. - Logged-in users: pass stable
context.userId.
Onboarding Events
Events power onboarding analytics, drop-off detection, and AI insights.
Supported event types:
FLOW_STARTED
- User begins a tracked onboarding flow.
- Send once when the flow is entered.
STEP_VIEWED
- User lands on or opens a specific step.
- Send whenever the current step changes.
STEP_COMPLETED
- User successfully completes a step.
- Send only after verified completion signal.
FLOW_COMPLETED
- User completes all required steps in the flow.
- Send once at successful finish.
ABANDONED
- User exits/stalls before completion.
- Send when inactivity timeout or explicit exit indicates drop-off.
Recommended minimum context for event quality:
productorserviceuserTargetflowSlugstepSlug(for step-level events)- stable identity (
context.sessionIdorcontext.userId)
Typical event sequence:
FLOW_STARTEDSTEP_VIEWED(step 1)STEP_COMPLETED(step 1)STEP_VIEWED(step 2)STEP_COMPLETED(step 2)FLOW_COMPLETED
Drop-off sequence example:
FLOW_STARTEDSTEP_VIEWED(step 1)STEP_VIEWED(step 2)ABANDONED
await client.sendEvent({
type: "STEP_COMPLETED",
context: {
service: "premium-support",
userTarget: "admin",
stepSlug: "connect_database",
},
});Feedback
await client.submitFeedback({
answerId: "ans_7xk9p2m",
rating: "GOOD",
comment: "Clear explanation and actionable advice",
});React Usage (Recommended)
import { OnboardingAIClient } from "@fluxyte/sdk";
import { OnboardingAIProvider } from "@fluxyte/sdk/react";
const client = new OnboardingAIClient(import.meta.env.VITE_FLUXYTE_API_KEY);
export function App() {
return (
<OnboardingAIProvider client={client}>
{/* your app */}
</OnboardingAIProvider>
);
}React Hooks
import { useChat } from "@fluxyte/sdk/react";
const { send, data, loading, error } = useChat();
await send({
message: "How do I connect my database?",
sessionId: "sess_123",
context: { service: "premium-support", userTarget: "admin" },
});import { useStreamingChat } from "@fluxyte/sdk/react";
const { text, answerId, confidence, streaming, start, stop } = useStreamingChat();
start({
message: "What's the next step?",
context: { product: "analytics", userTarget: "admin" },
});import { useVoiceChat } from "@fluxyte/sdk/react";
const { sendVoice, loading, data, error } = useVoiceChat();
const res = await sendVoice({
audioBase64: "BASE64_AUDIO",
mimeType: "audio/webm",
context: { product: "analytics", userTarget: "admin" },
synthesize: true,
voice: "alloy",
audioFormat: "mp3",
});
console.log(res.transcript);
console.log(res.reply);Multi-Target
Use context.product or context.service to isolate onboarding targets under one account (apps, APIs, and services).
Error Handling
import { APIError } from "@fluxyte/sdk";
try {
await client.chat(/* ... */);
} catch (err) {
if (err instanceof APIError) {
console.error(err.status, err.message);
}
}License
Commercial. See LICENSE.md.
