SDK Reference
Build a fully custom AI chat UI using Aerostack’s gateway SDK. Pick the package that matches your stack.
| Package | Runtime | Key export |
|---|---|---|
@aerostack/react | React 18/19 | useGatewayChat, useGatewayWallet, useGatewayUsage |
@aerostack/sdk | Any JS runtime | gateway.stream(), gateway.complete(), gateway.wallet() |
React SDK
Install
npm install @aerostack/reactSetup
Wrap your app with AerostackProvider once:
import { AerostackProvider } from '@aerostack/react'
export default function App({ children }) {
return (
<AerostackProvider
projectId="your-project-slug"
baseUrl="https://api.aerocall.ai/v1"
>
{children}
</AerostackProvider>
)
}useGatewayChat
The primary hook for building a custom chat UI. Manages message history, streaming, and quota in a single hook.
import { useGatewayChat } from '@aerostack/react'
function MyChatUI() {
const {
messages, // GatewayChatMessage[]
sendMessage, // (content: string) => Promise<void>
isStreaming, // boolean
error, // string | null
clearMessages, // () => void
wallet, // GatewayWallet | null
tokensUsedThisSession, // number
refreshWallet, // () => Promise<void>
} = useGatewayChat({
apiSlug: 'my-chatbot',
consumerKey: 'ask_live_xxx', // or token: userJwt
welcomeMessage: 'Hi! How can I help?',
})
return (
<div>
{messages.map(msg => (
<div key={msg.id} data-role={msg.role}>
{msg.content}
{msg.id === 'streaming' && <span className="cursor">▋</span>}
</div>
))}
{isStreaming && <p>Thinking…</p>}
{error && <p className="error">{error}</p>}
{wallet && (
<p>{wallet.balance.toLocaleString()} tokens remaining</p>
)}
<input
onKeyDown={e => {
if (e.key === 'Enter' && !isStreaming) {
sendMessage(e.currentTarget.value)
e.currentTarget.value = ''
}
}}
disabled={isStreaming}
placeholder="Type a message..."
/>
</div>
)
}Options:
| Prop | Type | Required | Description |
|---|---|---|---|
apiSlug | string | ✅ | Your gateway API slug |
consumerKey | string | — | ask_live_ key (consumer-key-only mode) |
token | string | — | User JWT (aerostack or byo-jwt mode) |
welcomeMessage | string | — | First message shown before user types |
Pass exactly one of consumerKey or token. For Aerostack Auth, use token: tokens?.accessToken from useAuth().
GatewayChatMessage shape:
interface GatewayChatMessage {
id: string
role: 'user' | 'assistant'
content: string
tokensUsed?: number // set on assistant messages after completion
timestamp: number
}GatewayWallet shape:
interface GatewayWallet {
balance: number // tokens remaining
total_purchased: number
total_consumed: number
plan_type: string // "free" | "flat" | "metered" | "tiered"
hard_limit: number | null
soft_limit: number | null
}useGatewayWallet
Just the quota — useful when you want to show a token balance somewhere other than the chat UI.
import { useGatewayWallet } from '@aerostack/react'
function QuotaIndicator() {
const { data, loading } = useGatewayWallet('my-chatbot', {
consumerKey: 'ask_live_xxx',
})
if (loading) return <span>Loading…</span>
return <span>{data?.balance.toLocaleString()} tokens left</span>
}Returns: { data: GatewayWallet | null, loading: boolean, error: string | null, refresh: () => Promise<void> }
useGatewayUsage
Usage stats for the current consumer — total tokens, total requests, and number of days covered.
import { useGatewayUsage } from '@aerostack/react'
function UsageStats() {
const { data } = useGatewayUsage('my-chatbot', {
consumerKey: 'ask_live_xxx',
days: 7,
})
return (
<div>
<p>{data?.total_tokens.toLocaleString()} tokens used (last {data?.days} days)</p>
<p>{data?.total_requests} requests</p>
</div>
)
}Returns: { data: GatewayUsage | null, loading: boolean, error: string | null, refresh: () => Promise<void> }
Auth integration
// User signs in via useAuth, JWT passed to useGatewayChat
import { useAuth, useGatewayChat } from '@aerostack/react'
function ChatPage() {
const { tokens, isAuthenticated } = useAuth()
const { messages, sendMessage, isStreaming } = useGatewayChat({
apiSlug: 'my-chatbot',
token: tokens?.accessToken, // automatically undefined before sign-in
})
if (!isAuthenticated) return <LoginForm />
return <MyChatUI messages={messages} onSend={sendMessage} streaming={isStreaming} />
}Universal SDK
Works in any JavaScript runtime — Vue, Svelte, React Native, Node.js server-side, vanilla JS.
Install
npm install @aerostack/sdkgateway.stream()
Stream chat completions token by token.
import { AerostackClient } from '@aerostack/sdk'
const ai = new AerostackClient({ baseUrl: 'https://api.aerocall.ai/v1' })
ai.gateway.setConsumerKey('ask_live_xxx')
await ai.gateway.stream({
apiSlug: 'my-chatbot',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'What is the capital of France?' },
],
onToken: (delta) => {
// Called for each token chunk as it arrives
process.stdout.write(delta) // or append to your UI state
},
onDone: ({ tokensUsed }) => {
console.log(`\nCompleted. Tokens used: ${tokensUsed}`)
},
})Options:
interface StreamOptions {
apiSlug: string
messages: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>
onToken: (delta: string) => void
onDone?: (result: { tokensUsed: number }) => void
onError?: (error: Error) => void
}gateway.complete()
Non-streaming — wait for the full response.
const result = await ai.gateway.complete({
apiSlug: 'my-chatbot',
messages: [{ role: 'user', content: 'Summarise this in one sentence.' }],
})
console.log(result.content) // full response string
console.log(result.tokensUsed) // numbergateway.connectWebSocket()
Real-time bidirectional connection — for voice, live agents, or custom protocols.
const ws = await ai.gateway.connectWebSocket({
apiSlug: 'my-realtime-api',
onMessage: (data) => {
console.log('Received:', data)
},
onClose: () => {
console.log('Connection closed')
},
})
ws.send(JSON.stringify({ type: 'input_audio', data: audioBuffer }))gateway.wallet()
Fetch current token balance and plan info.
const wallet = await ai.gateway.wallet('my-chatbot')
console.log(`${wallet.balance} tokens remaining`)
console.log(`Plan: ${wallet.plan_type}`)gateway.usage()
Fetch usage summary for the current consumer.
const usage = await ai.gateway.usage('my-chatbot', 30) // last 30 days
console.log(`${usage.total_tokens} tokens, ${usage.total_requests} requests`)Vue / Svelte / vanilla example
// Works in any framework that can call async functions
import { AerostackClient } from '@aerostack/sdk'
const ai = new AerostackClient({ baseUrl: 'https://api.aerocall.ai/v1' })
ai.gateway.setConsumerKey('ask_live_xxx')
// Vue composable
export function useChat(apiSlug: string) {
const messages = ref<Array<{ role: string; content: string }>>([])
const isStreaming = ref(false)
async function send(content: string) {
messages.value.push({ role: 'user', content })
messages.value.push({ role: 'assistant', content: '' })
isStreaming.value = true
await ai.gateway.stream({
apiSlug,
messages: messages.value.slice(0, -1),
onToken: delta => {
messages.value[messages.value.length - 1].content += delta
},
onDone: () => { isStreaming.value = false },
})
}
return { messages, isStreaming, send }
}The @aerostack/sdk package is framework-agnostic. The gateway.* methods are plain async functions and Promises — compose them however you like.