Quickstart
Get your first Ragen call working in under 5 minutes using the official
@ragenai/sdk for TypeScript / JavaScript. The SDK is the
recommended way to integrate with Ragen — it gives you typed responses,
ergonomic helpers like waitUntilProcessed(), automatic retries on
429/5xx, and streaming primitives that work in Node, edge runtimes, and
the browser.
If you can't use the SDK (Python, Go, curl, …), the same wire format is available via the REST API.
Prerequisites
- A Ragen AI account (sign up at app.ragen.ai)
- A project with at least one document uploaded to its knowledge base
- An API key (we'll create one below)
- Node.js 18+
Step 1: Create an API key
- Log in to your Ragen dashboard
- Navigate to Settings > API Keys
- Click Create API Key
- Enter a name (e.g., "My first key") and select the project this key should access
- Optionally enable Debug mode to save API conversations as threads for inspection (see Debug mode)
- Click Create
- Copy the key immediately — it's only shown once
Store your API key securely. It cannot be retrieved after creation — only a masked version is stored for display.
Step 2: Install the SDK
npm install @ragenai/sdk
# or
pnpm add @ragenai/sdk
# or
yarn add @ragenai/sdk
Step 3: Your first completion
import { Ragen } from "@ragenai/sdk";
const ragen = new Ragen({ apiKey: process.env.RAGEN_API_KEY });
const completion = await ragen.chat.completions.create({
assistantId: "123e4567-e89b-12d3-a456-426614174000",
messages: [
{ role: "user", content: "What is our refund policy?" },
],
});
console.log(completion.choices[0].message.content);
The response is grounded in the project's knowledge base — retrieval, reranking, and answer generation all happen server-side.
If most of your calls target the same project, set assistantId on the
client and omit it per call:
const ragen = new Ragen({
apiKey: process.env.RAGEN_API_KEY,
assistantId: "123e4567-e89b-12d3-a456-426614174000",
});
await ragen.chat.completions.create({
messages: [{ role: "user", content: "Hi" }],
});
Step 4: Stream tokens
const stream = ragen.chat.completions.stream({
assistantId: "123e4567-e89b-12d3-a456-426614174000",
messages: [{ role: "user", content: "Summarize our onboarding process" }],
stream_options: { include_usage: true },
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
if (chunk.usage) {
console.log(`\n\nUsed ${chunk.usage.total_tokens} tokens`);
}
}
For the common "wait for the whole thing" case, the SDK provides a helper that returns the full text:
const text = await ragen.chat.completions.streamToString({
assistantId: "123e4567-e89b-12d3-a456-426614174000",
messages: [{ role: "user", content: "Summarize the handbook" }],
});
Step 5: Upload files & manage assistants (optional)
// Upload a file into the knowledge base
const file = await ragen.files.upload("./handbook.pdf");
// Wait for embeddings to finish
await ragen.files.waitUntilProcessed(file.id);
// Or do both in one call
const ready = await ragen.files.uploadAndWait("./handbook.pdf");
// List, retrieve, delete
await ragen.files.list({ limit: 50 });
await ragen.files.retrieve(file.id);
await ragen.files.delete(file.id);
// Manage assistants (Ragen projects)
const assistant = await ragen.assistants.create({
name: "Support Bot",
instructions: "Be concise.",
});
await ragen.assistants.list();
await ragen.assistants.update(assistant.id, { name: "Support Bot v2" });
Error handling
All SDK errors extend RagenError. Pattern-match on the subclass to
handle specific HTTP statuses:
import {
RagenAuthError,
RagenNotFoundError,
RagenRateLimitError,
RagenAPIError,
RagenError,
} from "@ragenai/sdk";
try {
await ragen.chat.completions.create({
assistantId: "123e4567-e89b-12d3-a456-426614174000",
messages: [{ role: "user", content: "Hi" }],
});
} catch (err) {
if (err instanceof RagenRateLimitError) {
// 429 — already auto-retried, surface to caller
} else if (err instanceof RagenAuthError) {
// 401 — bad API key
} else if (err instanceof RagenNotFoundError) {
// 404
} else if (err instanceof RagenAPIError) {
// 5xx — already auto-retried
} else if (err instanceof RagenError) {
console.error(err.status, err.code, err.message);
} else {
throw err;
}
}
429 and 5xx responses are auto-retried with exponential backoff and
jitter, up to maxRetries times (default 2).
SDK configuration
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | process.env.RAGEN_API_KEY | API key. Required. |
assistantId | string | — | Default assistant_id used when not passed per-call. |
baseURL | string | https://api.ragen.ai/v1 | API base URL. Override for self-hosted deployments. |
maxRetries | number | 2 | Retry attempts on 429/5xx and transient errors. |
timeout | number (ms) | 30000 | Per-request timeout. |
fetch | typeof fetch | globalThis.fetch | Custom fetch implementation (e.g. for testing or polyfills). |
Next.js App Router (edge streaming)
A common pattern — proxy the SDK stream straight to the browser:
// app/api/chat/route.ts
import { Ragen } from "@ragenai/sdk";
export const runtime = "edge";
const ragen = new Ragen({
apiKey: process.env.RAGEN_API_KEY!,
assistantId: process.env.RAGEN_ASSISTANT_ID!,
});
export async function POST(req: Request): Promise<Response> {
const { messages } = await req.json();
const stream = ragen.chat.completions.stream({ messages });
const encoder = new TextEncoder();
const readable = new ReadableStream<Uint8Array>({
async start(controller) {
try {
for await (const chunk of stream) {
const piece = chunk.choices[0]?.delta?.content;
if (piece) {
controller.enqueue(encoder.encode(piece));
}
}
controller.close();
} catch (err) {
controller.error(err);
}
},
});
return new Response(readable, {
headers: {
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "no-cache",
},
});
}
Falling back to raw HTTP
When the SDK isn't an option (other languages, low-level integrations), the same endpoint is available over HTTP:
curl -X POST https://api.ragen.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"assistant_id": "123e4567-e89b-12d3-a456-426614174000",
"messages": [
{"role": "user", "content": "What is our refund policy?"}
]
}'
For quick bot integrations where you don't need the full chat-completions shape, a simpler single-prompt endpoint is also available:
curl -X POST https://api.ragen.ai/v1/chat \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "What is our refund policy?"}'
See the /v1/chat reference. New
integrations should prefer the SDK or /v1/chat/completions.
What's next?
- Chat Completions reference — full endpoint spec
- Files, Assistants, Threads & Messages — REST reference
- Concepts — projects, organizations, RAG, access control