Developer guide
Tour RAG API documentation
Multi-tenant RAG chatbot backend for East African tourism companies. One deployment, many operators — each with an API key, system prompt, and knowledge base. Designed so other products and websites can consume the API as a demo / MVP.
https://tourragapi.vercel.app/api/v1Interactive demo: /demo · Website snippet: /integrate
Quick start
Same flow as most payment / platform docs: create credentials → push data → call the action endpoint.
- Create a tenant with admin key → receive
api_keyonce. - Ingest chunks (tour packages, FAQs, routes).
- Chat with the tenant
x-api-key.
# 1) Create tenant
curl -s -X POST https://tourragapi.vercel.app/api/v1/tenants \
-H "Content-Type: application/json" \
-H "x-admin-key: $ADMIN_API_KEY" \
-d '{
"name": "Serengeti Trails",
"system_prompt": "You are a helpful safari booking assistant. Be concise."
}'
# 2) Ingest knowledge
curl -s -X POST https://tourragapi.vercel.app/api/v1/ingest \
-H "Content-Type: application/json" \
-H "x-admin-key: $ADMIN_API_KEY" \
-d '{
"tenant_id": "TENANT_UUID",
"chunks": [
{
"content": "3-day Serengeti safari from Arusha. From $890 pp.",
"metadata": { "type": "package", "days": 3 }
}
]
}'
# 3) Chat as the tenant
curl -s -X POST https://tourragapi.vercel.app/api/v1/chat \
-H "Content-Type: application/json" \
-H "x-api-key: $TENANT_API_KEY" \
-d '{
"message": "How much is a 3-day Serengeti safari?",
"session_id": "web-session-001"
}'Authentication
| Header | Used by | Notes |
|---|---|---|
x-admin-key | Tenants, Ingest | Server secret from env ADMIN_API_KEY |
x-api-key | Chat | Per-tenant key returned on create (shown once) |
Content-Type | All POST | application/json |
Errors
All failures share one shape (easy for clients to parse):
{
"error": "Human-readable message",
"code": "MACHINE_CODE"
}| HTTP | code | When |
|---|---|---|
| 400 | VALIDATION_ERROR, INVALID_JSON | Missing fields / bad body |
| 401 | UNAUTHORIZED | Bad or missing API / admin key |
| 404 | NOT_FOUND | Unknown tenant |
| 429 | RATE_LIMITED | Chat window exceeded (Retry-After header) |
| 500 | INTERNAL_ERROR, EMBEDDING_ERROR, … | Upstream or server failure |
Read /api/v1/health
Auth: None
Liveness probe. Use for uptime checks and load balancers.
curl -s https://tourragapi.vercel.app/api/v1/health
# {"status":"ok"}Write /api/v1/tenants
Auth: x-admin-key
Create a tenant (tourism company). The api_key is returned only in this response — store it securely.
Request body
{
"name": "Serengeti Trails",
"system_prompt": "You are a helpful safari booking assistant..."
}Response 201
{
"id": "uuid",
"name": "Serengeti Trails",
"system_prompt": "...",
"api_key": "hex-secret",
"created_at": "..."
}Read /api/v1/tenants/:id
Auth: x-admin-key
Fetch tenant metadata. Never returns api_key after creation.
curl -s https://tourragapi.vercel.app/api/v1/tenants/TENANT_UUID \
-H "x-admin-key: $ADMIN_API_KEY"Write /api/v1/ingest
Auth: x-admin-key
Push pre-chunked knowledge base text. The API embeds each chunk and stores vectors in Postgres (pgvector). It does not scrape or split documents for you.
Request body
{
"tenant_id": "uuid",
"chunks": [
{
"content": "string (max 8000 chars)",
"metadata": { "any": "json object" }
}
]
}Response 201
{ "inserted": 2 }Limits: max 50 chunks per request; each chunk max 8000 characters.
Write /api/v1/chat
Auth: x-api-key (tenant)
RAG chat: embed message → retrieve top documents for that tenant → generate answer → save history.
Request body
{
"message": "How much is a 3-day Serengeti safari?",
"session_id": "web-session-001"
}Response 200
{
"answer": "A 3-day Serengeti safari costs $890 per person.",
"sources": [
{
"id": "uuid",
"content": "...",
"metadata": {},
"similarity": 0.76
}
],
"session_id": "web-session-001"
}Limits & behaviour
- Message length: max 2000 characters on chat.
- Rate limit: 30 chat requests / tenant / 60 seconds.
- Retrieval: top 4 documents by cosine similarity.
- LLM: Groq Llama 3.3 70B primary, Gemini fallback.
- Embeddings: Gemini
gemini-embedding-001@ 768 dimensions.
Ingest capacity (tokens / full website)
| Limit | Value | Notes |
|---|---|---|
| Chunk size | 8,000 chars | ~1.5–2k tokens each (rule of thumb) |
| Chunks / request | 50 | Repeat calls to add more |
| Max per request | ~400k chars | 50 × 8,000 — still constrained by function timeout |
| DB hard cap | None in app code | Postgres/Supabase plan + embedding cost |
| ~1,000 web pages | Possible after chunking | Scrape → clean → chunk → many ingest batches. Prefer FAQs & packages first for sales demos. |
Vectors are not “tokens stored forever” — each chunk is one 768-dim embedding. Chat only retrieves the top 4 nearest chunks, so quality of chunks matters more than raw page count.
Next steps
Talk to the builder
Need this on your tourism website?
Call or message Cleven for demos, custom knowledge bases, multi-tenant setup, or embedding the chat widget on your operator site.