Getting Started
Get up and running with the Estuary Web SDK in minutes. This guide walks you through installation, configuration, and sending your first message to an AI character.
Prerequisites
Before you begin, ensure you have:
| Requirement | Details |
|---|---|
| Node.js | 18 or later |
| Estuary Account | Sign up at app.estuary-ai.com |
| API Key | Generated from your Estuary dashboard (starts with est_) |
| Character ID | The UUID of your AI character |
Installation
Install the SDK from npm:
npm install @estuary-ai/sdk
Or with other package managers:
yarn add @estuary-ai/sdk
pnpm add @estuary-ai/sdk
Quick Start
Here is a minimal example that connects to a character and exchanges text messages:
import { EstuaryClient } from '@estuary-ai/sdk';
const client = new EstuaryClient({
serverUrl: 'https://api.estuary-ai.com',
apiKey: 'est_your_api_key',
characterId: 'your-character-uuid',
playerId: 'user-123',
});
// Listen for bot responses
client.on('botResponse', (response) => {
if (response.isFinal) {
console.log('Bot:', response.text);
}
});
// Listen for errors
client.on('error', (err) => {
console.error('Error:', err.message);
});
// Connect and send a message
async function main() {
const session = await client.connect();
console.log('Connected! Session:', session.sessionId);
client.sendText('Hello! Tell me about yourself.');
}
main().catch(console.error);
Framework Integration (React / Next.js)
The SDK uses browser APIs (WebSocket, AudioContext, getUserMedia), so it cannot run during server-side rendering. In a React or Next.js project:
// In Next.js App Router, mark your component as a client component:
"use client";
import { EstuaryClient, ConnectionState } from '@estuary-ai/sdk';
If you use next/dynamic with ssr: false, the page that calls it must also be a client component in Next.js 16+:
"use client";
import dynamic from "next/dynamic";
const Chat = dynamic(() => import("@/components/Chat"), { ssr: false });
Always clean up the client on component unmount to avoid connection leaks:
useEffect(() => {
return () => {
void client.disconnect();
};
}, []);
What Happens Under the Hood
client.connect()opens a WebSocket connection to the Estuary server, authenticates with your API key, and returns aSessionInfoobject.client.sendText()sends your message over the WebSocket.- The server processes your message through the AI pipeline and streams the response back.
- The
botResponseevent fires for each chunk of the response. WhenisFinalistrue, the full response text is available.
Complete Example
This example demonstrates connection lifecycle handling, streaming responses, and cleanup:
import { EstuaryClient, ConnectionState } from '@estuary-ai/sdk';
const client = new EstuaryClient({
serverUrl: 'https://api.estuary-ai.com',
apiKey: 'est_your_api_key',
characterId: 'your-character-uuid',
playerId: 'user-123',
autoReconnect: true,
debug: true,
});
// Connection events
client.on('connected', (session) => {
console.log('Connected! Conversation:', session.conversationId);
});
client.on('disconnected', (reason) => {
console.log('Disconnected:', reason);
});
client.on('reconnecting', (attempt) => {
console.log(`Reconnecting (attempt ${attempt})...`);
});
// Response events
client.on('botResponse', (response) => {
if (response.isFinal) {
console.log('Bot:', response.text);
} else {
process.stdout.write(response.partial);
}
});
// Error handling
client.on('error', (err) => {
console.error('Error:', err.message);
});
client.on('authError', (message) => {
console.error('Authentication failed:', message);
});
client.on('quotaExceeded', (data) => {
console.warn(`Quota exceeded: ${data.message} (${data.current}/${data.limit})`);
});
// Main flow
async function main() {
try {
await client.connect();
client.sendText('Hello!');
} catch (err) {
console.error('Failed to connect:', err);
}
}
main();
// Clean up on exit
process.on('SIGINT', async () => {
await client.disconnect();
process.exit(0);
});
Opening a Share Link
If you have a permanent share link (a URL containing a share id, generated from the Estuary dashboard), you can let end users connect without distributing your apiKey. Use the static EstuaryClient.openShare() to exchange the share id for a short-lived sessionToken, then construct the client with that token:
import { EstuaryClient } from '@estuary-ai/sdk';
const share = await EstuaryClient.openShare(
'https://api.estuary-ai.com',
'share-abc-123', // share id from the share URL
);
const client = new EstuaryClient({
serverUrl: share.serverUrl,
sessionToken: share.sessionToken,
characterId: share.characterId,
playerId: share.playerId,
});
await client.connect();
client.sendText('Hello!');
share.character includes the character's display info (name, tagline, avatar, 3D model URL) so you can render a join screen before connecting.
Clients constructed with sessionToken cannot call REST APIs (client.memory, client.getCharacter()). Use a server-side proxy if you need those features.
Example Projects
Prefer to start from working code? Two open-source templates are built on the Web SDK:
- TypeScript SDK Demo -- A full Next.js app with text chat, voice (WebSocket + LiveKit), live transcription, an animated voice orb, and bot interrupts.
- Mattercraft WebAR Template -- A WebAR starter for browser-based augmented-reality characters.
See Example Projects for the full list across all platforms.
Next Steps
Now that you have a working connection:
- Core Concepts -- Understand the SDK architecture and event system
- Text Chat -- Learn about streaming responses, text-only mode, and interrupts
- Voice (WebSocket) -- Add voice input and output to your application
- Memory & Knowledge Graph -- Query persistent character memory