Building advanced chat interfaces with the Zeta Alpha API

I built a chat interface on Zeta Alpha's RAG API while exploring how retrieval-augmented chat should feel. React, with Tailwind and shadcn for the UI. The interesting problems turned out to have nothing to do with the model. They were about citations, file references, and showing your sources.
What the API gives you
The API splits into four services: authentication (an API key sent in an X-Auth header), document search, chat, and user document management. Search supports three retrieval modes (plain keyword, knn over vector embeddings, or a hybrid of the two), plus boolean filters, facets, and sorting by fields like date and citation count.
Chat comes as specialised agents: chat_with_pdf for a single document, chat_with_multiple_docs, a quizbot, and chat_with_dynamic_retrieval, which goes and finds relevant documents on its own. I used the last one. Every agent can return "evidences": source extracts that back up the answer.
Citations you can check
The evidences are what make RAG worth using, so most of my UI effort went there. Citations render as superscript markers in the reply. Click one and a modal shows the source text, formatted for reading, with a link out to the full document. If a chatbot claims something, you should be able to see where it got it from without leaving the conversation.
File references
The app also detects file mentions in messages and turns them into interactive elements marked with @: @App.js, @Chat.jsx, @components. Hovering shows a card with the file type and a short description. A small thing, but it makes conversations about a codebase much easier to follow.
Wiring it up
Each request sends the conversation history plus the agent identifier:
const payload = {
conversation: [
...messages.map(({ sender, content }) => ({ sender, content })),
userMessage,
],
agent_identifier: 'chat_with_dynamic_retrieval',
};
const response = await axios.post(
`${baseURL}/chat/response?tenant=zetaalpha`,
payload,
{
headers: {
'Content-Type': 'application/json',
'x-auth': process.env.REACT_APP_API_KEY,
},
}
);The response carries the message and its evidences, and parser components for message content, file references and citations turn that into the rendered chat. There is also a /chat/stream endpoint for token streaming; I used the synchronous one and leaned on loading states instead.
What I took from it
Grounded answers change the UX contract: people actually click citations when you make them clickable. Most of the real work in a RAG interface happens on the retrieval-and-evidence side of the screen, not the chat bubbles.