A vector database solves the retrieval part of a RAG pipeline. But a real product also needs to ingest content, pose queries against the database, rerank the results, and finally generate an answer — and it all needs to be callable from your own code. That's exactly what we've just released two official client libraries for: liviate-rag-py for Python and liviate-rag-dotnet for .NET.
Both wrap the same underlying pipeline — ingest, embed, retrieve, rerank, and (optionally) generate — in a handful of lines of code, instead of you having to build HTTP calls, authentication, and error handling around our API yourself.
Python: liviate-rag
pip install liviate-rag
from liviate_rag import RAGClient
client = RAGClient(api_key="...") # eller sæt LIVIATE_API_KEY
client.ingest("handbook.pdf", collection="hotel-kirstine")
result = client.query("Har I parkering?", collection="hotel-kirstine", model="anthropic/claude-sonnet-5")
print(result.answer)
print(result.sources)
If you want to control which model generates the answer yourself, you can stick to the retrieval part and fetch the ranked context alone:
context = client.retrieve("Har I parkering?", collection="hotel-kirstine", top_k=5)
For asynchronous code, there's AsyncRAGClient with the same method names, ready to use with async/await.
ingest() automatically detects whether the input is a file, a URL, a plain text string, or a stream, and supports PDF, DOCX, Markdown, TXT, CSV, JSON, and HTML. If you need to crawl an entire website instead of a single file, there's a separate, explicit method for that: client.ingest_site("https://example.com", collection="x", max_pages=200).
.NET: Liviate.Rag
dotnet add package Liviate.Rag
using Liviate.Rag;
await using var client = new RagClient(); // eller new RagClient(apiKey: "sk-...")
await client.IngestAsync("handbook.pdf", "hotel-kirstine");
var result = await client.QueryAsync("Har I parkering?", "hotel-kirstine", "anthropic/claude-sonnet-5");
Console.WriteLine(result.Answer);
The .NET version is a port of the Python library, but with one structural difference: there's no separate sync and async client. .NET's built-in async/Task makes that split unnecessary, so all I/O calls on RagClient are async Task (or IAsyncEnumerable for streamed generation).
The same retrieval-only pattern exists here:
var context = await client.RetrieveAsync("Har I parkering?", "hotel-kirstine", topK: 5);
For an ingest that shouldn't block while it runs, there's StartIngest, which returns an IngestJob immediately instead of waiting for it to finish.
Honest About the Status
The two libraries aren't at the same stage. The Python version is a v1 scaffold, built on reasonable assumptions about some of the request and response formats, where a few contracts against the backend itself haven't been finally confirmed yet — this is flagged directly in the code with comments where relevant.
The .NET port came afterward and was built directly against contracts already confirmed live in production: Ingest → Retrieve → Query are all verified end-to-end against the real pipeline, not just a mock. On the other hand, IngestSiteAsync in .NET isn't implemented yet — it throws a NotImplementedException, so if you need to crawl an entire website from .NET today, you do it by calling IngestAsync with a list of individual page URLs instead.
Both libraries are open source, and both accept issues and PRs.
Where It Fits In
The libraries cover the calling layer itself. What they call into is the same managed vector database and RAG pipeline we've written about before — scaling, indexing, and isolation between customers handled for you, without you having to operate the database behind it yourself.
Are you building something that needs to ingest your own content and answer based on it? Get in touch, and let's talk about where you could start.