xAI Grok Integration
Grok conversations that survive a cold start
The xAI API is stateless: every call takes the full history. DialogueDB is where that history lives between calls, so a restart is not the end of the conversation.
Every turn from Grok is persisted, ready to be reloaded on the next request.
How it works
Two parallel paths from the server you already have
Your OpenAI SDK client keeps calling xAI's endpoint. DialogueDB sits alongside it as a second client that stores each turn and hands it back on the next request. Nothing wraps the model call.
Your server
Model call
chat.completions.create
Runs directly to Grok. Nothing wraps it.
Persistence
saveMessage · loadMessages
Each turn stored, reloaded on the next request.
What else DialogueDB adds
Three more things a Grok app runs into next
All handled by the same client. No second service, no vector database.
Every user gets their own conversation
Pass a namespace when you save and when you read. Two users share the same dialogue id and never see each other, with no tenant column in your app.
Returning users do not start over
Facts worth keeping live as Memory objects, separate from any single conversation. The next session with the same user opens with what you chose to remember.
Answer follow-ups from earlier sessions
Search past exchanges by meaning to pull the right context into the next call. No embeddings pipeline, no vector database to run alongside your app.
Nothing extra to write
OpenAI-compatible, so the mapping is a pass-through
The shape DialogueDB stores is the shape Grok's API takes. Three things you'd otherwise have to write, that you don't.
Compatibility check
OpenAI SDK · xAI endpoint
Role names
system, user, and assistant map straight through — no assistant-to-model swap either direction.
Content shape
Stored content is a string. Grok takes a string. No blocks, no parts arrays, no wire-format translation.
Client library
The OpenAI SDK you already have works pointed at https://api.x.ai/v1. Nothing wraps the model call.
Ready — no adapter class required
The same client does more
Six more things the same install covers, without another SDK to add.
Continue a conversation on any worker
Load the dialogue by id and the message array rebuilds from scratch, on whichever instance takes the next request.
dialogue.loadMessages({ order: "asc" })Facts and preferences across sessions
Store what the assistant should remember about a user, independent of any single conversation.
db.createMemory()Recall by meaning before you call Grok
Search stored memories against the new turn and put the matches in the system message.
db.searchMemories()Token counts alongside the message
Keep usage.total_tokens on the message it belongs to, so cost per conversation is a query rather than a guess.
metadata: { totalTokens }Branch a conversation for a sub-task
Parent and child dialogues let a delegated task keep its own transcript without polluting the main thread.
dialogue.createThread()Per-conversation scratchpad
Give each conversation its own state object for workflow flags, partial results, or in-progress context.
dialogue.saveState()Install in 3 steps
From npm install to the first persisted turn, in under five minutes.
Install the client
npm install dialogue-dbSet both API keys
DIALOGUE_DB_API_KEY=...
XAI_API_KEY=...Save each turn
await dialogue.saveMessage({
role: "assistant",
content: reply,
})No credit card. Free tier to start. Starter is $29/month when usage grows.
The reference example
One turn, a cold reload, then a second turn continued from the reloaded history.
Runs on Edge and serverless too. The client is HTTP-only, with no connection pool and no native dependencies.
Hover a step to see the lines it maps to.
Reference example
xai
The whole bridge is two functions in src/persist.ts: one maps a loaded dialogue to the message array the xAI API takes, the other loads a dialogue with its messages in order. Every read and write is scoped to a namespace.
Where DialogueDB fits
Four ways to keep a Grok conversation, and what each one asks of you.
| Approach | Survives a restart | Portable across providers | Memory and search included |
|---|---|---|---|
| In-process array | No | Yes, until the process ends | No |
| Your own table | Yes | Yes, once you design the schema | Add a vector store and a pipeline |
| Standalone memory service | Yes, for extracted facts | Usually | Memory yes, full transcript no |
| DialogueDB | Yes | Yes, role and content only | Yes, one API |
If you know chat completions, you already know this
Everything nests under a namespace, and the concepts line up with the message array you already build.
The data model
namespace
scoped to one user or tenant
dialogue
messages, threads, state
indexed for semantic search
memory
facts and preferences, cross-session
indexed for semantic search
| xAI chat completions | DialogueDB |
|---|---|
messages: ChatCompletionMessageParam[] you pass to chat.completions.create | dialogue.loadMessages({ order: 'asc' }) rebuilds it |
ChatCompletionMessageParam | message, stored as sent |
role: 'system' | 'user' | 'assistant' | Same role field on stored messages, unchanged |
content string | Same content field, stored as sent |
The system prompt message | Composed from db.searchMemories() at request time |
usage.prompt_tokens, usage.completion_tokens | metadata on the assistant message |
A stored message is a role and a content value, which is exactly what an OpenAI-compatible endpoint takes. That is why the reference mapper is a few lines long and why the same stored conversation is not tied to one provider.
What DialogueDB sees
Only what's needed for conversation storage
Your call to Grok goes straight from your server to xAI. DialogueDB sits beside that request, never inside it.
The client only receives what you explicitly send: message content, memory values, and the identifiers you scope them with. Your xAI key, your user tokens, and everything else in your app never pass through it.
What we receive
- Message content and roles
- Memory values and metadata
- Dialogue and namespace IDs
What we never see
- Your xAI API key
- User authentication tokens
- Your xAI base URL, system prompts, or model settings
Two independent calls from your server
Your server
src/turn.ts
Your code decides what goes where.
nothing routed through us
xAI
api.x.ai/v1
The model call goes direct. DialogueDB never sees the request or the credential.
DialogueDB
Messages and memory only
Receives what you explicitly save. Nothing implicit, nothing extra.
Frequently asked questions
One API for messages, memory, and search
Add it to your Grok app in minutes.