Short, focused snippets for the most common tasks with the
@4players/odin-cortex SDK. Each is runnable on its own — set
CORTEX_API_KEY and your project id, then run with npx tsx <file>.ts.
Every sample starts from the same client:
import { CortexClient } from "@4players/odin-cortex";
const PROJECT_ID = "__YOUR_PROJECT_ID__";
const client = new CortexClient({
baseUrl: process.env.BASE_URL ?? "https://ots.odin.4players.io",
apiKey: process.env.CORTEX_API_KEY,
});
const project = client.project(PROJECT_ID);
Create and start a session
const session = await project.sessions.create({
title: "Script Test Session",
externalRoomId: "room-1",
idleTimeout: 60,
autoStart: true,
});
console.log("Session created:", session.id);
If you don’t pass autoStart, start it yourself:
List sessions, then collect a transcript
const sessions = await project.sessions.list();
for (const s of sessions) {
console.log(`[${s.status}] ${s.id}`);
}
const session = await project.sessions.create({
title: "Script Test",
externalRoomId: "hello",
idleTimeout: 60,
});
await session.start();
await new Promise((r) => setTimeout(r, 30_000));
await session.stop();
const messages = await session.getMessages();
console.log(`Got ${messages.length} message(s)`);
Update the bot’s user data
The bot’s userData (the profile it presents in the ODIN room) lives in project settings.
Use the partial update() to change just that one field — everything else is preserved:
const botUserData = {
name: "Transcription Bot",
role: "bot",
avatar: "https://example.com/bot.png",
};
const updated = await project.settings.update({ botUserData });
console.log("Updated bot userData:", updated.botUserData);
Use project.settings.upsert() instead when you want to set the full configuration
(including the token provider).
Watch a session and its transcript live
const sessionId = process.env.SESSION_ID ?? "__YOUR_SESSION_ID__";
const sessionSub = project.sessions.watch(sessionId);
sessionSub.onSnapshot((session) => {
if (!session) return console.log("[session] deleted or not found");
console.log(`[session] ${session.title} — status=${session.status}`);
});
const session = await project.sessions.get(sessionId);
const messageSub = session.watchMessages();
messageSub.onSnapshot((messages, changes) => {
for (const change of changes) {
if (change.type === "added") {
console.log(` + ${change.data.senderName}: ${change.data.content}`);
}
}
});
process.on("SIGINT", () => {
sessionSub.unsubscribe();
messageSub.unsubscribe();
process.exit(0);
});
Watch the whole sessions collection
const sub = project.sessions.watch();
sub.onSnapshot((sessions, changes) => {
console.log(`\n[snapshot] ${sessions.length} session(s)`);
for (const change of changes) {
console.log(` ${change.type.padEnd(8)} ${change.id} (${change.data.status})`);
}
});
sub.onError((err) => console.error("[error]", err));
process.on("SIGINT", () => {
sub.unsubscribe();
process.exit(0);
});