Developers

Your documents, answerable over HTTP.

Retrieval-augmented generation is four hard problems wearing a trench coat: chunking, embeddings, a vector store, and stopping the model inventing an answer when it doesn't have one. We run all four. You send a file and a question, and get back an answer grounded in that file, or an honest refusal.

Free to start. No card. A live console at /api-docs runs against your own key.

Before you open a vector database tab

The demo takes a weekend. The rest takes a quarter.

“We'll just embed the PDFs and query them.”

Then the PDFs have tables that flatten into nonsense, the chunks split mid-sentence, a question spans two documents, and someone asks for a total that retrieval can only approximate. Each fix is a week you didn't plan for.

4

separate systems to build, tune and keep running before the first honest answer

“Why did it say that? It's not in the document.”

The failure that kills internal trust isn't a wrong lookup, it's a confident invention. Once a team catches the assistant making up a figure, they stop using it, and no amount of retrieval tuning wins them back.

1

fabricated answer is enough to end the pilot

Four calls, start to answer

Upload a file. Ask it a question.

There is no index to provision, no embedding model to pick, no schema to declare. Post the document you already have, wait for it to become ready, then ask in plain language.

upload → poll → open → ask
# 1. Send the document. One key, and it carries
#    its own account, so no tenant header to get wrong.
curl https://api.smartcampaigns.ai/api/v1/datasets \
  -H "Authorization: Bearer rag_live_…" \
  -F "name=Policy handbook" \
  -F "[email protected]"

# → { "dataset": { "id": 412, "status": "pending" } }

# 2. Chunking + embedding run async. Poll until ready.
curl https://api.smartcampaigns.ai/api/v1/datasets/412 \
  -H "Authorization: Bearer rag_live_…"

# → { "dataset": { "status": "ready" } }

# 3. Open a conversation against it. It keeps the
#    thread's history, so follow-ups have context.
curl https://api.smartcampaigns.ai/api/v1/conversations \
  -H "Authorization: Bearer rag_live_…" \
  -d '{"dataset_id": 412}'

# → { "conversation": { "id": 77 } }

# 4. Ask it anything.
curl https://api.smartcampaigns.ai/api/v1/\
  conversations/77/messages \
  -H "Authorization: Bearer rag_live_…" \
  -d '{"content":
     "how much notice for unpaid leave?"}'

{ "assistant_message": {
    "content": "Four weeks in writing to
      your line manager (§7.3). Under four weeks
      needs director approval." } }

# X-RAG-Quota-Remaining: 4999
1

Send what you already have

.csv, .pdf, .docx, .txt, .json, .md, .markdown. No pre-processing, no conversion step, no manual chunking. Upload the handbook, the price list, the export: whatever the answer actually lives in.

2

Retrieval you don't have to tune

Vector similarity with a keyword fallback, so an exact product code or clause number still lands when the embedding is ambiguous. Chunk sizes, overlap and thresholds are ours to maintain, not yours.

3

Arithmetic that isn't guessed

Upload a CSV and it is imported as structured records, so totals and breakdowns are computed in the database rather than estimated by a language model. Breakdowns add up to their own total because they were summed, not written.

4

Metering you can invoice against

Every billable response carries X-RAG-Quota-Remaining, and /usage/api_quota reports the same figures per key. One key per client you serve, so usage separates cleanly before the invoice arrives.

What you're not building

The unglamorous 80% is the part we run.

Every item here is a thing a team building this in-house discovers in month two, after the prototype has already been demoed to a director.

Document parsing that keeps tables

A price table flattened into a wall of words retrieves badly and reads worse. DOCX tables are parsed as retrievable rows, so a figure stays attached to the thing it describes instead of dissolving into prose. PDF tables are extracted as text today, so send tabular data as CSV or DOCX when the numbers matter.

DOCX tables

Grounding, and honest refusal

When the retrieved passages don't support an answer, the API says so instead of producing a fluent guess. This is the difference between a tool a team keeps using and one they quietly abandon.

The trust problem

Tenant isolation by construction

A key resolves its own account from the stored row, never from the request. A partner holding a key for one client cannot address another's data, whatever else they put in the payload.

Multi-client safe

Revocation that means revoked

Keys are stored as digests, so a database dump yields nothing usable, and revocation is checked on every request rather than at the next refresh. Cut one integration without touching the others.

Breach containment

Streaming or single response

Take the answer in one JSON body, or stream tokens to a chat UI. Reading answers back, listing workspaces and rating a reply are free and never count against your allowance.

Your UI, your call

Re-upload without re-wiring

Documents are versioned, so replacing a handbook with next quarter's edition doesn't orphan the conversations that referenced it or force you to rebuild an index by hand.

Versioned knowledge

Priced per question asked

Quote your own client a fixed number.

A question means a question asked. Reading results back, listing workspaces or rating a reply are free and never count against your allowance, so a chat UI that re-renders a thread costs you nothing.

Starter
KES 6,370.00 / month
1,000 questions a month
Then KES 13.00 per question
Agency
KES 25,870.00 / month
5,000 questions a month
Then KES 13.00 per question
Scale
KES 97,370.00 / month
25,000 questions a month
Then KES 13.00 per question

Prices shown in KES at today's rate. Create a key yourself under Settings → API keys. No sales call, no onboarding form. The full reference and a live console that runs against your own key are at /api-docs.

Fair questions

What you're probably about to ask

Why not just use a model provider's built-in file search?

For a handful of documents and a forgiving use case, you should: it's cheaper and it's right there. The reasons teams end up here instead are arithmetic and refusal. File search answers numeric questions by reading passages and estimating; we import tabular data as structured records and compute over them, so a breakdown adds up to its own total. And we would rather return "the documents don't say" than a fluent guess, which is a product decision more than a technical one.

Is my data used to train models?

No. Your documents are embedded and stored for retrieval against your own account only, and a key can never read another account's data. Delete a dataset and its embeddings go with it.

What happens when the answer isn't in my documents?

You get told that, rather than a plausible-sounding invention. Requests authenticated with an API key fail closed: on a fact-shaped question the API would otherwise have to guess, it declines instead, and a stated price the retrieved sources don't support is suppressed rather than returned. A program consuming your answers cannot tell a hedge from a fact, so it should never be handed one. Signed-in users in the dashboard see low-confidence answers flagged rather than withheld, because a person can weigh a caveat that a script cannot.

How big can a document be?

Row and dataset limits come from your plan rather than from the API, and the current ceilings are listed on the pricing page and returned live from the usage limits endpoint. Very large files import asynchronously, so poll the dataset until its status is ready.

Can I run this for several clients?

That's what the key model is built for. Mint one key per client, each bound to its own account, each metered separately per calendar month. Revoking one leaves the others untouched, and the API quota endpoint gives you per-key figures to bill from.

Which file types can I send?

CSV, PDF, DOCX, TXT, JSON and Markdown. CSV is imported row by row so totals are computed rather than estimated; the document formats are chunked and embedded for passage retrieval. DOCX tables are preserved as retrievable rows, so send tabular data as CSV or DOCX when the numbers matter.

Send your first document in about five minutes.

Sign up, mint a key under Settings → API keys, and POST a file. The live console at /api-docs runs against your own account, so the first call you make is a real one.

Get an API key