Next.js SDK
Server and client utilities for Next.js. Supports App Router and Pages Router.
npm install @ainative/next-sdk
The Next.js SDK re-exports all React SDK hooks (useChat, useCredits, useMemory, etc.) from @ainative/next-sdk/client and adds server-side utilities via @ainative/next-sdk/server.
Server Client
Use createServerClient in API routes and Server Components to call the AINative API from the server. The client exposes chat.completions.create(), credits.balance(), deployments.*, and rerank().
// app/api/chat/route.ts
import { createServerClient } from '@ainative/next-sdk/server';
export async function POST(req: Request) {
const { messages } = await req.json();
const client = createServerClient({
apiKey: process.env.AINATIVE_API_KEY!,
});
const response = await client.chat.completions.create({
messages,
preferred_model: 'meta-llama/llama-3.3-70b-instruct',
temperature: 0.7,
});
return Response.json(response);
}
ServerClientConfig
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | required | JWT token or API key |
baseUrl | string | https://api.ainative.studio/api/v1 | API base URL |
ServerClient Methods
| Method | Description |
|---|---|
chat.completions.create(request) | Create a chat completion |
credits.balance() | Get credit balance |
deployments.list() | List deployments |
deployments.get(id) | Get a deployment |
deployments.create(options) | Create a deployment |
deployments.teardown(id) | Delete a deployment |
deployments.chatCompletions(id, messages, options?) | Run inference on a deployment |
rerank(query, documents, options?) | Rerank documents |
Auth Middleware (App Router)
Protect API routes with withAuth. It reads the JWT from the ainative_token cookie, validates it, and passes the session and apiKey to your handler.
// app/api/chat/route.ts
import { withAuth, createServerClient } from '@ainative/next-sdk/server';
export const POST = withAuth(async (req, { session, apiKey }) => {
const client = createServerClient({ apiKey });
const { messages } = await req.json();
const response = await client.chat.completions.create({
messages,
preferred_model: 'meta-llama/llama-3.3-70b-instruct',
});
return Response.json(response);
});
If the cookie is missing or the JWT is expired, withAuth returns a 401 response automatically.
Auth Middleware (Pages Router)
// pages/api/chat.ts
import { withAuthPages, createServerClient } from '@ainative/next-sdk/server';
export default withAuthPages(async (req, res, { session, apiKey }) => {
const client = createServerClient({ apiKey });
const response = await client.chat.completions.create({
messages: req.body.messages,
});
res.status(200).json(response);
});
Session Helpers
Read the current user session in Server Components:
// app/dashboard/page.tsx
import { getSession, getApiKey, createServerClient } from '@ainative/next-sdk/server';
import { redirect } from 'next/navigation';
export default async function DashboardPage() {
const session = await getSession();
if (!session) redirect('/login');
const apiKey = await getApiKey();
const client = createServerClient({ apiKey: apiKey! });
const balance = await client.credits.balance();
return (
<div>
<h1>Welcome, {session.email}</h1>
<p>Credits remaining: {balance.remaining_credits.toLocaleString()}</p>
</div>
);
}
| Function | Router | Description |
|---|---|---|
getSession(cookieName?) | App Router | Async -- reads from cookies() |
getApiKey(cookieName?) | App Router | Async -- returns raw JWT string |
getSessionFromCookie(cookieHeader, cookieName?) | Pages Router | Sync -- parses cookie header |
getApiKeyFromCookie(cookieHeader, cookieName?) | Pages Router | Sync -- extracts token string |
Client Components
For client-side interactivity, use the hooks re-exported from the React SDK. Import from @ainative/next-sdk/client (or @ainative/next-sdk directly).
'use client';
import { AINativeProvider, useChat, useCredits } from '@ainative/next-sdk/client';
function ChatUI() {
const { messages, sendMessage, isLoading, reset } = useChat({
model: 'meta-llama/llama-3.3-70b-instruct',
});
const { balance } = useCredits();
const [input, setInput] = React.useState('');
const handleSend = async () => {
if (!input.trim()) return;
setInput('');
await sendMessage([...messages, { role: 'user', content: input }]);
};
return (
<div>
<p>{balance?.remaining_credits} credits remaining</p>
{messages.map((msg, i) => (
<div key={i}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
{isLoading && <p>Thinking...</p>}
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
/>
<button onClick={handleSend} disabled={isLoading}>Send</button>
<button onClick={reset}>Clear</button>
</div>
);
}
// Wrap with provider (pass API key from server via props or env)
export default function ChatPage({ apiKey }: { apiKey: string }) {
return (
<AINativeProvider config={{ apiKey }}>
<ChatUI />
</AINativeProvider>
);
}
All hooks from the React SDK are available: useChat, useCredits, useMemory, useAgent, useTask, useThread, and the deployment hooks.
Full Example: Chat Page with Server + Client
A complete Next.js page that combines server-side auth with client-side chat.
API Route
// app/api/chat/route.ts
import { withAuth, createServerClient } from '@ainative/next-sdk/server';
export const POST = withAuth(async (req, { apiKey }) => {
const client = createServerClient({ apiKey });
const { messages } = await req.json();
const response = await client.chat.completions.create({
messages,
preferred_model: 'meta-llama/llama-3.3-70b-instruct',
});
return Response.json(response);
});
Server Component (layout)
// app/chat/page.tsx
import { getSession, getApiKey } from '@ainative/next-sdk/server';
import { redirect } from 'next/navigation';
import ChatClient from './chat-client';
export default async function ChatPage() {
const session = await getSession();
if (!session) redirect('/login');
const apiKey = await getApiKey();
return (
<main>
<h1>Chat</h1>
<p>Logged in as {session.email}</p>
<ChatClient apiKey={apiKey!} />
</main>
);
}
Client Component
// app/chat/chat-client.tsx
'use client';
import React, { useState } from 'react';
import { AINativeProvider, useChat, useCredits, useMemory } from '@ainative/next-sdk/client';
function ChatInterface() {
const { messages, sendMessage, isLoading, error, reset } = useChat({
model: 'meta-llama/llama-3.3-70b-instruct',
});
const { balance } = useCredits();
const { remember } = useMemory();
const [input, setInput] = useState('');
const handleSend = async () => {
if (!input.trim() || isLoading) return;
const text = input;
setInput('');
const response = await sendMessage([
...messages,
{ role: 'user', content: text },
]);
// Optionally store the exchange in memory
if (response) {
await remember(`User asked: ${text}`, { tags: ['chat'] });
}
};
return (
<div style={{ maxWidth: 640, margin: '0 auto' }}>
{balance && (
<div style={{ textAlign: 'right', fontSize: 14, color: '#666' }}>
{balance.remaining_credits.toLocaleString()} credits | {balance.plan}
</div>
)}
<div style={{ minHeight: 400, padding: 16 }}>
{messages.map((msg, i) => (
<div key={i} style={{
textAlign: msg.role === 'user' ? 'right' : 'left',
margin: '8px 0',
}}>
<span style={{
display: 'inline-block',
padding: '8px 12px',
borderRadius: 12,
background: msg.role === 'user' ? '#0066ff' : '#f0f0f0',
color: msg.role === 'user' ? '#fff' : '#000',
maxWidth: '80%',
}}>
{msg.content}
</span>
</div>
))}
{isLoading && <div style={{ color: '#999' }}>Thinking...</div>}
{error && <div style={{ color: 'red' }}>Error: {error.message}</div>}
</div>
<div style={{ display: 'flex', gap: 8 }}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
placeholder="Type a message..."
style={{ flex: 1, padding: '8px 12px' }}
/>
<button onClick={handleSend} disabled={isLoading}>Send</button>
<button onClick={reset}>Clear</button>
</div>
</div>
);
}
export default function ChatClient({ apiKey }: { apiKey: string }) {
return (
<AINativeProvider config={{ apiKey }}>
<ChatInterface />
</AINativeProvider>
);
}
Environment Variables
| Variable | Description |
|---|---|
AINATIVE_API_KEY | Server-side API key (used in createServerClient) |
The server client does not auto-read environment variables -- you must pass the API key explicitly via createServerClient({ apiKey }).
TypeScript Types
import type {
Session,
ServerClient,
ServerClientConfig,
WithAuthOptions,
} from '@ainative/next-sdk/server';
import type {
AINativeConfig,
Message,
ChatCompletionResponse,
CreditBalance,
AINativeError,
} from '@ainative/next-sdk/client';
Next Steps
- React SDK -- Hook API reference and standalone examples
- Build a Chatbot -- Step-by-step tutorial
- ZeroMemory -- Persistent memory for AI
- API Reference -- REST API documentation