backend
API DOCUMENTATION
This document provides details for all available endpoints in the Nexus API.
Nexus API Documentation
Base URL: https://api.gitavedanta.in (Production)
This document provides details for all available endpoints in the Nexus API. As implemented today, the following routes are public and do not require a Bearer JWT:
/health/v1/auth/*/v1/appConfig/v1/appConfig/:domain/v1/localizations/languages/v1/anuvaadTranslations/v1/anuvaadTranslations/:runId/v1/docs/v1/docs/:section/:slugPOST /v1/docsPOST /v2/vedavaani
All other documented routes require a valid JSON Web Token (JWT) in the
Authorization header.
For /v1/bookDetails, /v1/verses, /v1/chapterSummary, /v1/vedavaani, and
/v1/vedavaani/verseAssistant, successful 2xx responses are obfuscated by
default. Call POST /v1/session first, then send the returned
X-Obfuscation-Token header on those requests. Errors remain plain JSON.
Debug Mode: Pass the optional header x-debug-raw-response: true to bypass
obfuscation and receive plain JSON responses (development/testing only).
Table of Contents
- Health Check
- Authentication
- App Config
- Localization Languages
- Obfuscation Session
- Account
- Books / Book Details
- Verses
- Anuvaad Translations
- Chapter Summary
- Vedavaani - Spiritual Mentor
- Vedavaani Verse Assistant
- DocHub
Global Response Envelope
Every response — success or error — is wrapped in a consistent JSON envelope.
Success
{
"success": true,
"data": <payload>,
"cached": true,
"pagination": {
"limit": 50,
"offset": 0,
"count": 18
}
}
Error
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
}
}
Error Codes
| HTTP Status | error.code | Cause |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing or malformed request fields |
| 401 | UNAUTHORIZED | Missing / expired / invalid Bearer token |
| 429 | RATE_LIMITED | Route-group request window exceeded |
| 429 | VEDAVAANI_DAILY_BUDGET_EXCEEDED | Vedavaani daily AI credit budget exhausted |
| 429 | VEDAVAANI_CONCURRENCY_LIMIT | Vedavaani in-flight concurrency cap reached |
| 404 | NOT_FOUND | Resource does not exist |
| 500 | DB_ERROR | Database query failed |
| 500 | AUTH_FAILED | OTP verification failed unexpectedly |
| 500 | AUTH_REFRESH_FAILED | Token refresh failed unexpectedly |
| 500 | INTERNAL_ERROR | Unhandled server error |
Rate Limiting
Nexus v1 applies app-layer rate limits and returns throttled responses in the
standard error envelope with a Retry-After header.
Current v1 launch policy is intentionally narrow:
POST /v1/auth/otpandPOST /v1/auth/tokenare limited by both IP and normalized email.POST /v1/anuvaadTranslationsis limited by IP because it triggers backend work.POST /v1/vedavaaniandPOST /v1/vedavaani/verseAssistantenforce shared daily internal AI credits plus a shared per-user concurrency cap.GET /v1/appConfig,GET /v1/appConfig/:domain,GET /v1/localizations/languages,GET /v1/docs,GET /v1/docs/:section/:slug, andPOST /v1/docsdo not have additional launch-time application throttles.POST /v1/session,DELETE /v1/session,/v1/bookDetails,/v1/verses,/v1/chapterSummary,/v1/account, and other non-Vedavaani authenticated routes do not have additional launch-time application throttles.- IP-based auth throttles trust forwarded client-IP headers only when the immediate peer is a trusted private or loopback proxy hop.
Vedavaani daily credit accounting:
/v1/vedavaanicosts10units/v1/vedavaani/verseAssistantcosts4units- daily allowance comes from
chat_configuration.payload.LIMITS.BASIC, converted at10units per credit - the budget resets at midnight
Asia/Kolkata
1. Health Check
Returns the current status of the API server.
- URL:
/health - Method:
GET - Auth required: No
Example Request
curl -X GET https://api.gitavedanta.in/health
Example Response
{
"status": "ok",
"timestamp": "2026-03-09T10:24:34.123Z"
}
2. Authentication
All endpoints except /health, /v1/auth/*, /v1/appConfig,
/v1/appConfig/:domain, /v1/localizations/languages,
/v1/anuvaadTranslations, /v1/anuvaadTranslations/:runId, /v1/docs,
/v1/docs/:section/:slug, POST /v1/docs, and POST /v2/vedavaani require a
valid Bearer JWT issued by Supabase. Access tokens expire after 1 hour; clients
should use the returned refresh token with POST /v1/auth/refresh to obtain a
new session.
2.1 POST /v1/auth/otp
Requests a one-time password (OTP) to be sent to the user's email address for authentication.
- URL:
/v1/auth/otp - Method:
POST - Auth required: No
- Headers:
Content-Type: application/json
This route is rate-limited by IP and normalized email. Throttled responses
return 429 RATE_LIMITED with Retry-After.
Request Body
| Parameter | Type | Required | Validation |
|---|---|---|---|
email | String | Yes | Must be a valid email |
Example Request
curl -X POST https://api.gitavedanta.in/v1/auth/otp \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'
Example Response
{
"success": true,
"data": {
"message": "OTP sent successfully"
}
}
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid email format |
| 429 | RATE_LIMITED | Per-IP or per-email auth throttle hit |
| 500 | OTP_DISPATCH_FAILED | Failed to send OTP (Supabase error) |
| 500 | INTERNAL_ERROR | Unexpected server error |
2.2 POST /v1/auth/token
Verifies a Supabase OTP and returns a session token. The returned
refresh_token should be stored by the client and exchanged through
POST /v1/auth/refresh when the 1-hour access token expires.
- URL:
/v1/auth/token - Method:
POST - Auth required: No
- Headers:
Content-Type: application/json
Request Body
| Parameter | Type | Required | Validation |
|---|---|---|---|
email | String | Yes | Must be a valid email |
otp | String | Yes | Must be exactly 6 digits |
Example Request
curl -X POST https://api.gitavedanta.in/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"otp": "123456"
}'
Example Response
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI... (JWT token string)",
"refresh_token": "v1.Mb3Jlc...",
"user_id": "a1b2c3d4-e5f6-..."
}
}
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid email or OTP format |
| 401 | UNAUTHORIZED | OTP is wrong or expired |
| 429 | RATE_LIMITED | Per-IP or per-email auth throttle hit |
| 500 | AUTH_FAILED | Unexpected Supabase auth error |
2.3 POST /v1/auth/refresh
Exchanges a valid Supabase refresh token for a new session token pair. The response also includes the authenticated user's current Vedavaani daily credit status for the active India day.
- URL:
/v1/auth/refresh - Method:
POST - Auth required: No
- Headers:
Content-Type: application/json
Request Body
| Parameter | Type | Required | Validation |
|---|---|---|---|
refresh_token | String | Yes | Must be a non-empty string |
Example Request
curl -X POST https://api.gitavedanta.in/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "v1.Mb3Jlc..."
}'
Example Response
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI... (JWT token string)",
"refresh_token": "v1.N3dUb2tlbg...",
"user_id": "a1b2c3d4-e5f6-...",
"credits": {
"remaining_display": 28,
"daily_total_display": 30,
"reset_at": "2026-04-07T18:30:00.000Z",
"timezone": "Asia/Kolkata"
}
}
}
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid JSON or missing refresh_token |
| 401 | UNAUTHORIZED | Refresh token is invalid, expired, or revoked |
| 429 | RATE_LIMITED | Per-IP auth throttle hit |
| 500 | AUTH_REFRESH_FAILED | Unexpected Supabase refresh error |
2.4 POST /v1/auth/logout
Invalidates the current Supabase access token through the logout flow. This
route is mounted under /v1/auth and does not use JWT middleware, but it does
require a Bearer token in the Authorization header so Nexus can forward the
logout to Supabase.
- URL:
/v1/auth/logout - Method:
POST - Auth required: Bearer access token in
Authorizationheader - Headers:
Authorization: Bearer <token>
Example Request
curl -X POST https://api.gitavedanta.in/v1/auth/logout \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"success": true,
"data": {
"message": "Logged out successfully"
}
}
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing or malformed Authorization header |
| 500 | INTERNAL_ERROR | Unexpected logout failure |
3. App Config
Returns the current non-secret mobile app configuration served by Nexus.
3.1 GET /v1/appConfig
Returns all current non-secret mobile app configuration domains from
public.app_config_documents.
- URL:
/v1/appConfig - Method:
GET - Auth required: No
- Obfuscation required: No
- Cached: Yes, 5 minutes in-memory on the API
Optional Headers
| Header | Description |
|---|---|
x-bypass-cache | Skip the API cache and read the latest row |
If-None-Match | Revalidate against the current config ETag |
Example Request
curl -X GET https://api.gitavedanta.in/v1/appConfig
Example Success Response
{
"success": true,
"data": {
"app_configuration": {
"domain": "app_configuration",
"version": 12,
"updatedAt": "2026-03-30T12:00:00.000Z",
"config": {
"minSupportedVersion": "1.2.3",
"maintenanceMode": false
}
},
"chat_configuration": {
"domain": "chat_configuration",
"version": 4,
"updatedAt": "2026-03-30T12:00:00.000Z",
"config": {
"welcomeMessage": "Hari Om"
}
}
},
"cached": false
}
Response Headers
ETag: W/"app-config-all-<domain>:<version>|..."Cache-Control: public, max-age=300, must-revalidate
Response 304
Returned when If-None-Match matches the current config ETag.
Notes
- This endpoint is intended only for client-safe configuration.
- Newly added SQL domains are returned automatically by
/v1/appConfig. - Do not store secrets, private URLs, API keys, JWT material, or internal-only
operational flags in the backing
app_config_documentstable. - Browser reads are intentionally CORS-allowed from any origin on this route.
3.2 GET /v1/appConfig/:domain
Returns one non-secret config domain document.
- URL:
/v1/appConfig/:domain - Method:
GET - Auth required: No
domain is dynamic. Any row name present in public.app_config_documents that
passes validation can be requested.
Example Request
curl -X GET https://api.gitavedanta.in/v1/appConfig/ui_config
Example Response
{
"success": true,
"data": {
"domain": "ui_config",
"version": 7,
"updatedAt": "2026-03-30T12:00:00.000Z",
"config": {
"showNewBadge": true
}
},
"cached": false
}
Response Headers
ETag: W/"app-config-<domain>-v<version>"Cache-Control: public, max-age=300, must-revalidate
Notes
- Browser reads are intentionally CORS-allowed from any origin on this route.
domainis data-driven frompublic.app_config_documents; it is not hardcoded in Nexus route definitions.
4. Localization Languages
Returns the currently implemented localization language catalog used by frontend language selectors and localized scripture fetches.
- URL:
/v1/localizations/languages - Method:
GET - Auth required: No
- Obfuscation required: No
Example Request
curl -X GET https://api.gitavedanta.in/v1/localizations/languages
Example Response
{
"success": true,
"data": [
{
"code": "hi",
"name": "Hindi"
},
{
"code": "or",
"name": "Odia"
}
]
}
Data Object Fields
| Field | Type | Description |
|---|---|---|
code | String | Language code accepted by localization-aware scripture endpoints such as GET /v1/verses?lang=<code> |
name | String | Human-readable language name for client language pickers |
Frontend Notes
- Use this endpoint to populate localization selectors instead of hardcoding the currently implemented language list in the client.
- When a user selects a language, pass the returned
codeto backend localization-aware endpoints such asGET /v1/verses. - This API does not localize static app UI copy such as menus, buttons, headings, settings labels, or onboarding text. Those localizations must be implemented in the frontend client.
5. Obfuscation Session
Bootstrap route for obfuscated scripture and Vedavaani responses.
5.1 POST /v1/session
Creates a lightweight obfuscation session for protected scripture and Vedavaani
routes. The server returns a signed obfuscationToken that the client sends
back on subsequent data requests via X-Obfuscation-Token, plus the current
Vedavaani daily credit status for the authenticated user.
- URL:
/v1/session - Method:
POST - Auth required: Yes (
Authorization: Bearer <token>)
Example Request
curl -X POST https://api.gitavedanta.in/v1/session \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"success": true,
"data": {
"obfuscationToken": "<signed-token>",
"version": "v1",
"expiresAt": 1774881930,
"credits": {
"remaining_display": 28.8,
"daily_total_display": 30,
"reset_at": "2026-04-07T18:30:00.000Z",
"timezone": "Asia/Kolkata"
}
},
"cached": false
}
Use the returned token as X-Obfuscation-Token on:
/v1/bookDetails/v1/verses/v1/chapterSummary/v1/vedavaani/v1/vedavaani/verseAssistant
5.2 DELETE /v1/session
Invalidates the obfuscation session for the current JWT. Called on logout to ensure the current token can no longer be used.
- URL:
/v1/session - Method:
DELETE - Auth required: Yes (
Authorization: Bearer <token>)
Example Request
curl -X DELETE https://api.gitavedanta.in/v1/session \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"success": true,
"data": {
"message": "Obfuscation session invalidated"
}
}
6. Account
6.1 GET /v1/account/credits
Returns the authenticated user's current Vedavaani daily credit status as plain JSON. This is the lightweight resync route for clients that need to refresh the authoritative backend credit view without making a Vedavaani request.
- URL:
/v1/account/credits - Method:
GET - Auth required: Yes (
Authorization: Bearer <token>) - Auth subject claim resolution order:
sub,subject, thenuser_metadata.sub
Example Request
curl https://api.gitavedanta.in/v1/account/credits \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"success": true,
"data": {
"credits": {
"remaining_display": 27.6,
"daily_total_display": 30,
"reset_at": "2026-04-07T18:30:00.000Z",
"timezone": "Asia/Kolkata"
}
},
"cached": false
}
6.2 DELETE /v1/account
Deletes the authenticated user's account through the Nexus account flow.
- URL:
/v1/account - Method:
DELETE - Auth required: Yes (
Authorization: Bearer <token>)
Example Request
curl -X DELETE https://api.gitavedanta.in/v1/account \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response
{
"success": true,
"data": {
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"deleted": true
}
}
7. Books / Book Details
Fetches all available books from the database with their metadata and properties.
- URL:
/v1/bookDetails - Method:
GET - Auth required: Yes (
Authorization: Bearer <token>) - Obfuscation required: Yes (
X-Obfuscation-Token: <token>) - Cached: Yes (10 min, keyed by
lang)
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lang | String | No | - | Localize bookName using a supported language code. Missing or empty localized values fall back to the English/base book name |
Example Request
curl -X GET "https://api.gitavedanta.in/v1/bookDetails?lang=hi" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN"
Example Request (Debug Mode - Raw Response)
curl -X GET https://api.gitavedanta.in/v1/bookDetails \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "x-debug-raw-response: true"
Example Success Response
Successful responses are obfuscated octet-stream bodies with:
Content-Type: application/octet-streamX-Obfuscated: 1X-Obfuscation-Version: v1
When x-debug-raw-response: true is passed, responses are returned as plain
JSON with:
Content-Type: application/jsonX-Debug-Raw-Response: true
Error responses remain standard JSON.
Decoded Example Payload
{
"success": true,
"cached": false,
"data": [
{
"bookName": "Bhagavad Gita",
"bookImage": "https://api.gitavedanta.in/storage/v1/object/public/books/bg.png",
"bookHashWord": "bg",
"chapterDetailedLink": "https://api.gitavedanta.in/storage/v1/object/public/...",
"chapterSummaryLink": "https://api.gitavedanta.in/storage/v1/object/public/...",
"features": [
{ "name": "tags", "value": ["Must Read"] },
{ "name": "priority", "value": 4 }
]
}
]
}
Data Object Fields
| Field | Type | Description |
|---|---|---|
bookName | String | Full display name of the book, localized when lang is provided with English fallback |
bookImage | String | Storage URL of the book cover image |
bookHashWord | String | Short identifier used as a query key (e.g. bg) |
chapterDetailedLink | String | Storage URL for chapter detailed data |
chapterSummaryLink | String | Storage URL for chapter summary data |
features | Array of Objects | Raw JSONB array from the database |
Note: All
*LinkandbookImagestorage URLs are automatically rewritten fromsb.gitavedanta.in→api.gitavedanta.inbefore being returned.
Frontend Localization Notes
- Use
/v1/localizations/languagesto fetch the supported language list for your picker UI. - Send the selected language
codeas thelangquery parameter. - If no localized row exists yet for a book, or the localized value is empty,
the backend falls back to the English/base
book_details.book_name.
8. Verses
Fetches verses from public.chapter_detailed table. Supports pagination and
filtering by book and chapter.
- URL:
/v1/verses - Method:
GET - Auth required: Yes (
Authorization: Bearer <token>) - Obfuscation required: Yes (
X-Obfuscation-Token: <token>) - Cached: Yes (10 min, keyed by
book + chp_num + limit + offset)
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | Integer | No | 500 | Number of verses to return (max: 1000) |
offset | Integer | No | 0 | Offset to start fetching from |
book | String | No | - | Filter verses by book_hashname |
chp_num | Integer | No | - | Filter verses by chapter_number |
lang | String | No | - | Localize translation and commentary using a supported language code. When omitted, returns the default English translation and commentary |
Example Request
curl -X GET "https://api.gitavedanta.in/v1/verses?book=bg&chp_num=1&lang=hi&limit=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN"
Example Request (Debug Mode - Raw Response)
curl -X GET "https://api.gitavedanta.in/v1/verses?book=bg&chp_num=1&limit=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "x-debug-raw-response: true"
Decoded Example Payload
{
"success": true,
"cached": false,
"pagination": {
"limit": 2,
"offset": 0,
"count": 2
},
"data": [
{
"verseNumber": 1,
"chapterNumber": 1,
"text": "धृतराष्ट्र उवाच ...",
"transliteration": "dhṛtarāṣṭra uvāca ...",
"translation": "Dhritarashtra said...",
"commentary": "In this verse...",
"bookHashName": "bg"
},
{
"verseNumber": 2,
"chapterNumber": 1,
"text": "सञ्जय उवाच ...",
"transliteration": "sañjaya uvāca ...",
"translation": "Sanjaya said...",
"commentary": "Sanjaya describes...",
"bookHashName": "bg"
}
]
}
Frontend Localization Notes
- Use
/v1/localizations/languagesto fetch the supported language list for your picker UI. - Send the selected language
codeas thelangquery parameter. - If no localized row exists yet for a verse, the backend returns empty strings
for localized
translationandcommentary. - Static client UI strings are not localized by the API and must be handled by the frontend app.
9. Anuvaad Translations
Triggers the Anuvaad-based translation backfill pipeline used for localized
verse translation and commentary rows. The request returns immediately with
a run ID.
⚠️ Backend Only: This endpoint is exclusive to backend jobs and automated pipelines. It must not be triggered from frontend applications or mobile apps.
9.1 POST /v1/anuvaadTranslations
- URL:
/v1/anuvaadTranslations - Method:
POST - Auth required: No
- Obfuscation required: No
This endpoint is rate-limited per IP and is intentionally stricter than normal public reads because it can trigger backend work. It is backend/operations-only and must not be called from frontend or mobile clients.
Example Trigger Request
curl -X POST "https://api.gitavedanta.in/v1/anuvaadTranslations" \
-H "Content-Type: application/json" \
-d '{
"scope": "book",
"mode": "incremental",
"language": ["hi", "ta"],
"book": ["bg", "kenaupanishad"],
"dryRun": true
}'
Example Trigger Response
{
"success": true,
"data": {
"runId": "2026-04-02T10-00-00-000Z",
"status": "queued",
"message": "Translation job accepted and queued.",
"startedAt": "2026-04-02T10:00:00.000Z"
}
}
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
scope | "book" or "chapter" | No | High-level content scope. book translates book_details, chapter_summary, and chapter_detailed. chapter translates only chapter_summary and chapter_detailed. If omitted, Nexus preserves the legacy verse-only flow and translates chapter_detailed only. |
mode | "full" or "incremental" | No | full overwrites localized content in scope. incremental translates only missing localized fields. |
language | String or String Array | Yes | One code, many codes, or "all" |
book | String or String Array | No in legacy mode, Yes for scoped jobs | One or more book identifiers, or "all" |
chapter | Number, String, or Array | Required for scope: "chapter" | One or more chapter filters, or "all" |
limit | Integer | No | Per-domain source row limit |
offset | Integer | No | Per-domain source row offset |
overwriteExisting | Boolean | No | Legacy alias for mode: "full" |
dryRun | Boolean | No | Skip DB writes |
cooldownMinMs | Integer | No | Request-batch cooldown min override |
cooldownMaxMs | Integer | No | Request-batch cooldown max override |
requestTimeoutMs | Integer | No | Per-request timeout override |
Scope and Mode Behavior
scope: "book"translates all localizable content for the selected books:book_details.book_name,chapter_summary.name_translated,chapter_summary.summary,chapter_detailed.translation, andchapter_detailed.commentary.scope: "chapter"translates onlychapter_summaryandchapter_detailedfor the selected book/chapter combinations.mode: "full"re-translates and replaces localized content in scope.mode: "incremental"translates only missing localized fields and preserves existing localized values.
9.2 GET /v1/anuvaadTranslations/:runId
Returns the status of a previously started translation run.
- URL:
/v1/anuvaadTranslations/:runId - Method:
GET - Auth required: No
- Obfuscation required: No
Example Request
curl -X GET "https://api.gitavedanta.in/v1/anuvaadTranslations/2026-04-02T10-00-00-000Z"
Example Response (Completed)
{
"success": true,
"data": {
"runId": "2026-04-02T10-00-00-000Z",
"status": "completed",
"message": "Translation job completed.",
"startedAt": "2026-04-02T10:00:00.000Z",
"completedAt": "2026-04-02T10:05:00.000Z",
"summary": {
"counts": {
"translated_rows": 120
}
}
}
}
If the run is still processing, the response returns queued or running. When
complete, it returns summary, failedRows, and skippedRows. If the run ID
is unknown, the API returns 404 NOT_FOUND.
10. Chapter Summary
Fetches chapter summaries from the public.chapter_summary table. Supports
pagination and filtering by book.
- URL:
/v1/chapterSummary - Method:
GET - Auth required: Yes (
Authorization: Bearer <token>) - Obfuscation required: Yes (
X-Obfuscation-Token: <token>) - Cached: Yes (10 min, keyed by
bookHashName + lang + limit + offset)
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | Integer | No | 500 | Number of chapters to return (max: 1000) |
offset | Integer | No | 0 | Offset to start fetching from |
bookHashName | String | No | - | Filter by book short ID (e.g. bg). Returns all books if omitted. |
lang | String | No | - | Localize nameTranslated and summary using a supported language code. Missing or empty localized values fall back to English/base fields |
Example Request
curl -X GET "https://api.gitavedanta.in/v1/chapterSummary?bookHashName=bg&lang=hi&limit=1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN"
Example Request (Debug Mode - Raw Response)
curl -X GET "https://api.gitavedanta.in/v1/chapterSummary?bookHashName=bg&limit=1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "x-debug-raw-response: true"
Frontend Localization Notes
- Use
/v1/localizations/languagesto fetch the supported language list for your picker UI. - Send the selected language
codeas thelangquery parameter. - If no localized chapter-summary row exists yet, or the localized
name_translated/summaryvalue is empty, the backend falls back to the English/basechapter_summaryvalue.
Example Response
{
"success": true,
"cached": false,
"pagination": {
"limit": 1,
"offset": 0,
"count": 1
},
"data": [
{
"chapterNumber": 1,
"name": "अर्जुनविषादयोग",
"nameTranslated": "Arjuna Visada Yoga",
"verseCount": 47,
"nameMeaning": "The Yoga of Arjuna's Dejection",
"summary": "The first chapter introduces the setting...",
"bookHashName": "bg"
}
]
}
11. Vedavaani - Spiritual Mentor
Vedavaani is an AI-powered spiritual mentor that provides contextual wisdom from
sacred scriptures. It processes user queries along with optional conversation
history, retrieves relevant verses, and generates personalized responses using
intelligent routing and reflection. Successful v1 responses include a credits
object that reports the post-charge remaining daily display balance for the
authenticated user.
- URL:
/v1/vedavaani - Method:
POST - Auth required: Yes (
Authorization: Bearer <token>) - Obfuscation required: Yes (
X-Obfuscation-Token: <token>) - Headers:
Content-Type: application/json
Admission controls on this route:
- daily Vedavaani budget charge of
10internal units - shared per-user concurrency cap of
2 - no additional generic per-IP or per-user launch throttle beyond the shared Vedavaani budget/concurrency admission controls
- successful responses include
data.creditswith the post-charge remaining balance
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | String | Yes | The user's message / question. Whitespace-only values are rejected after trimming. |
messages | Array | No | Conversation history (array of {role, content} objects). Entries with blank content are ignored server-side. |
previous_summary | String | No | Summary of previous conversation context |
cited_verse_ids | Array | No | IDs of verses already cited (to avoid repetition) |
cited_themes | Array | No | Themes already covered (to avoid repetition) |
guided_listener_consecutive | Number | No | Count of consecutive guided_listener turns (default: 0) |
response_intent_history | String[] (max 3) | No | Last 3 response intents. Frontend stores and returns each turn. Values: question, reflection, presence, scripture |
spiritual_profile | Object or null | No | Emerging user spiritual profile. Frontend stores and returns. |
active_scripture_thread | Object or null | No | Current scripture thread. Frontend stores and returns. |
Example Request
curl -X POST https://api.gitavedanta.in/v1/vedavaani \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "I feel lost and don'\''t know what to do",
"messages": [
{ "role": "user", "content": "I'\''ve been struggling lately" },
{ "role": "assistant", "content": "Tell me more about what you'\''re going through." }
],
"previous_summary": "",
"cited_verse_ids": [],
"cited_themes": [],
"guided_listener_consecutive": 0
}'
Example Request (Debug Mode - Raw Response)
curl -X POST https://api.gitavedanta.in/v1/vedavaani \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "Content-Type: application/json" \
-H "x-debug-raw-response: true" \
-d '{
"query": "I feel lost and don'\''t know what to do",
"messages": [],
"previous_summary": ""
}'
Decoded Example Response
{
"success": true,
"data": {
"answer": "That feeling of being lost can be overwhelming...",
"mode": "listener",
"confidence_score": 0.72,
"sources": [
{
"id": "123",
"chapterNumber": 2,
"verseNumber": 47,
"text": "कर्मण्येवाधिकारस्ते...",
"translation": "You have a right to perform your prescribed duties...",
"commentary": "This verse teaches us...",
"bookHashName": "bg",
"similarity": 0.72
}
],
"updated_summary": "User expressed feeling lost and directionless.",
"cited_verse_ids": [],
"cited_themes": [],
"guided_listener_consecutive": 0,
"credits": {
"remaining_display": 29,
"daily_total_display": 30,
"reset_at": "2026-04-07T18:30:00.000Z",
"timezone": "Asia/Kolkata",
"request_cost_display": 1
},
"debug": {
"reasoning": "User is sharing raw emotion, listener mode appropriate.",
"emotional_peak": "feeling lost and directionless",
"tone_register": "grounding",
"conversation_arc": "disclosing",
"topic_label": "existential uncertainty",
"holding": false,
"closing": false,
"reflection_verdict": "send",
"correction_applied": false,
"retrieval_ran": true
}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
answer | String | The AI-generated response |
mode | String | Response mode: listener, guided_listener, blended, mentor |
confidence_score | Number | Top verse relevance score (0–1) |
sources | Array | Ranked scripture verses used as context |
updated_summary | String | Updated conversation summary for next turn |
cited_verse_ids | Array | Verse IDs cited so far |
cited_themes | Array | Themes covered so far |
guided_listener_consecutive | Number | Consecutive guided_listener turn count |
response_intent_history | String[] | Updated history — frontend must store and return on next request |
spiritual_profile | Object or null | Updated profile — frontend must store and return on next request |
active_scripture_thread | Object or null | Updated thread — frontend must store and return on next request |
debug | Object | Internal pipeline debug info |
Response Modes
- listener: Reflective acknowledgment with a clarifying question; no scripture cited. Used when the user needs empathetic presence.
- guided_listener: Light scripture context with an open question. Used when the user has asked for scripture but needs more emotional groundwork.
- blended: Balanced response with one or two verses and a reflective question. The default for most conversations.
- mentor: Direct scriptural guidance and teaching. Used when the user is ready and confidence in verse relevance is high.
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing query or invalid body format |
| 401 | UNAUTHORIZED | Missing or invalid Bearer token |
| 429 | RATE_LIMITED | Request window exceeded |
| 429 | VEDAVAANI_DAILY_BUDGET_EXCEEDED | Daily Vedavaani budget exhausted |
| 429 | VEDAVAANI_CONCURRENCY_LIMIT | Vedavaani concurrency cap reached |
| 500 | VECTOR_SEARCH_ERROR | Vector similarity search failed |
| 500 | INTERNAL_ERROR | AI pipeline error (Groq/Voyage API issue) |
Context & State Management
Vedavaani maintains conversation context across turns:
- Scout Phase: Summarizes conversation and extracts emotional state, topic arc, and readiness level
- Retrieval: Generates embeddings and performs vector + keyword search across scriptures
- Reranking: Uses semantic reranking to surface the most relevant verses
- Routing: Selects response mode based on user readiness, emotional tone, and scriptural demand
- Generation: Crafts response with scripture citations and guided reflection
- Reflection: Self-checks response for thread drift and triggers regeneration if needed
12. Vedavaani Verse Assistant
Verse-scoped Vedavaani v1 route for the verse screen. The backend loads an English-only Verse Context Pack from the anchor verse, keeps the current verse as primary context, and only widens into broader retrieval when the user explicitly asks to compare or broaden or when the local context is insufficient.
- URL:
/v1/vedavaani/verseAssistant - Method:
POST - Auth required: Yes (
Authorization: Bearer <token>) - Obfuscation required: Yes (
X-Obfuscation-Token: <token>) - Headers:
Content-Type: application/json
Admission controls on this route:
- daily Vedavaani budget charge of
4internal units - shared per-user concurrency cap of
2 - no additional generic per-IP or per-user launch throttle beyond the shared Vedavaani budget/concurrency admission controls
- successful responses include
data.creditswith the post-charge remaining balance andrequest_cost_displayof0.4
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | String | Yes | The user's verse-related question. Whitespace-only values are rejected after trimming. |
anchor_verse.book | String | Yes | Book hashname for the anchor verse |
anchor_verse.chapter_number | Number | Yes | Chapter number for the anchor verse |
anchor_verse.verse_number | Number | Yes | Verse number for the anchor verse |
messages | Array | No | Same conversation message format as /v1/vedavaani; blank history entries are ignored. |
previous_summary | String | No | Prior running summary for this verse thread |
previous_conversation_state | Object | No | Prior v1 conversation state |
cited_verse_ids | Array | No | Verse IDs already cited |
cited_themes | Array | No | Themes already covered |
guided_listener_consecutive | Number | No | Consecutive guided-listener count |
response_intent_history | String[] (max 3) | No | Last 3 response intents |
spiritual_profile | Object or null | No | Same optional v1 profile object |
active_scripture_thread | Object or null | No | Same optional v1 scripture thread |
verse_thread_summary | String or null | No | Optional short summary for this verse-only thread. null is normalized to an empty string |
Example Request
curl -X POST https://api.gitavedanta.in/v1/vedavaani/verseAssistant \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Obfuscation-Token: OBFUSCATION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "What does this verse mean in practice?",
"anchor_verse": {
"book": "bg",
"chapter_number": 2,
"verse_number": 47
},
"messages": [],
"previous_summary": ""
}'
Note: Do not send
verse_context. The backend fetches verse text, transliteration, translation, and commentary from Postgres automatically usinganchor_verse.
Decoded Example Response
Response shape matches POST /v1/vedavaani.
Additional route semantics:
sources[0]remains the anchor verse when the request succeedsdebug.retrieval_ranisfalsefor ordinary verse-scoped follow-ups that do not widen beyond the local verse packdebug.retrieval_ranbecomestruewhen supplemental retrieval runs
Verse Context Pack
The backend builds this context from Postgres and does not require the client to send verse text or commentary:
- Current verse id, book, chapter, verse number
- Current verse text, transliteration, translation, commentary
- Previous verse text, translation, commentary when available
- Next verse text, translation, commentary when available
- Optional chapter title and chapter summary
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing query, incomplete anchor_verse, or invalid body format |
| 401 | UNAUTHORIZED | Missing or invalid Bearer token |
| 429 | RATE_LIMITED | Request window exceeded |
| 429 | VEDAVAANI_DAILY_BUDGET_EXCEEDED | Daily Vedavaani budget exhausted |
| 429 | VEDAVAANI_CONCURRENCY_LIMIT | Vedavaani concurrency cap reached |
| 404 | NOT_FOUND | Anchor verse does not exist |
| 500 | DB_ERROR | Verse context lookup failed |
| 500 | INTERNAL_ERROR | AI pipeline error |
13. DocHub
DocHub stores canonical raw Markdown in Supabase Storage and routing metadata in
Postgres. All DocHub routes are public. Reads return published content by
default, and clients can opt into include_unpublished=true when they need the
full index. Browser CORS is restricted to the DocHub allowlist:
https://dochub.gitavedanta.inhttp://localhost:5173http://127.0.0.1:5173http://dochub.localhost:3001
13.1 GET /v1/docs
- URL:
/v1/docs - Method:
GET - Auth required: No
- CORS: Restricted to the DocHub allowlist for browser requests
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
section | String | No | — | One of backend, app, design, website, product |
q | String | No | — | Simple search across title, summary, and search text |
tag | String | No | — | Exact tag filter |
limit | Integer | No | 20 | Min 1, max 100 |
offset | Integer | No | 0 | Min 0, max 5000 |
include_unpublished | Boolean | No | false | Include unpublished docs in the result set |
Notes
- Search matches against title, summary, and derived
search_text. - The response uses the standard success envelope with
pagination.
13.2 GET /v1/docs/:section/:slug
- URL:
/v1/docs/:section/:slug - Method:
GET - Auth required: No
- CORS: Same DocHub allowlist as
GET /v1/docs
Returns one published DocHub document with markdown_content as a plain string.
The backend does not render Markdown to HTML in v1.
13.3 POST /v1/docs
- URL:
/v1/docs - Method:
POST - Auth required: No
- CORS: Same DocHub allowlist as
GET /v1/docs - Headers:
Content-Type: application/json
Upserts the metadata row in public.docs_documents and uploads canonical raw
Markdown to the dochub-docs bucket at {section}/{slug}.md. Re-posting the
same section + slug updates the existing document.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
section | String | Yes | One of backend, app, design, website, product |
slug | String | Yes | Lowercase hyphen-separated document slug |
title | String | Yes | Document title, max 200 chars |
markdown_content | String | Yes | Canonical raw Markdown source |
summary | String | No | Summary, max 500 chars |
tags | String[] | No | Up to 20 tag strings |
source_repo | String | No | Optional source repository reference |
is_published | Boolean | No | Defaults to true |
Example Response
{
"success": true,
"data": {
"section": "backend",
"slug": "api",
"title": "API",
"storage_path": "backend/api.md",
"is_published": true,
"updated_at": "2026-04-21T12:00:00.000Z"
}
}
13.4 DELETE /v1/docs/:section/:slug
- URL:
/v1/docs/:section/:slug - Method:
DELETE - Auth required: No
- CORS: Same DocHub allowlist as
GET /v1/docs
Deletes the canonical Markdown object from the dochub-docs bucket and removes
the matching metadata row from public.docs_documents.
Example Response
{
"success": true,
"data": {
"section": "backend",
"slug": "api",
"deleted": true
}
}
Error Responses
| Status | error.code | Reason |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid section or slug |
| 404 | NOT_FOUND | Document does not exist |
| 500 | INTERNAL_ERROR | Metadata or storage deletion failed |
14. V2 Endpoints
The V2 API represents the next generation of the Vedavaani spiritual mentor pipeline, featuring enhanced emotional intelligence, episodic memory, semantic recall, and multi-agent orchestration.
Base URL (Production): https://api.gitavedanta.in/v2
14.1 POST /v2/vedavaani
Advanced AI-powered spiritual mentor with emotional intelligence, memory systems, and multi-agent orchestration.
- URL:
/v2/vedavaani - Method:
POST - Auth required: No in the current live route wiring
- Headers:
Content-Type: application/json
POST /v2/vedavaani is currently mounted without the v1 JWT middleware or
obfuscation middleware. Clients may still choose to send Authorization, but
the live route does not require it today.
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | String | Yes | The user's message / question (max 4000 chars) |
session_id | String | Yes | Unique session identifier for tracking conversation context |
user_id | String | No | User identifier for episodic memory retrieval |
messages | Array | No | Conversation history (array of {role, content} objects). Roles: "user" or "assistant" |
previous_summary | String | No | Summary of previous conversation context |
cited_verse_ids | Array | No | IDs of verses already cited (to avoid repetition) |
cited_themes | Array | No | Themes already covered (to avoid repetition) |
guided_listener_consecutive | Number | No | Count of consecutive guided_listener turns (default: 0, min: 0) |
Example Request
curl -X POST https://api.gitavedanta.in/v2/vedavaani \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "I feel lost and don'\''t know what to do next",
"session_id": "session-abc-123",
"user_id": "user-xyz-789",
"messages": [
{ "role": "user", "content": "I'\''ve been struggling with direction lately" },
{ "role": "assistant", "content": "Tell me more about what you'\''re experiencing." }
],
"previous_summary": "User exploring feelings of uncertainty",
"cited_verse_ids": [],
"cited_themes": [],
"guided_listener_consecutive": 0
}'
Example Response
{
"success": true,
"data": {
"answer": "That feeling of being lost can be deeply unsettling...",
"mode": "guided_listener",
"confidence_score": 0.78,
"sources": [
{
"verse_id": "bg-2-47",
"book_hashname": "bg",
"chapter_number": 2,
"verse_number": 47,
"verse_text": "कर्मण्येवाधिकारस्ते...",
"translation": "You have a right to perform your prescribed duties...",
"commentary": "This verse teaches detachment from results...",
"similarity_score": 0.82
}
],
"updated_summary": "User expressed feeling lost and seeking direction in life",
"cited_verse_ids": ["bg-2-47"],
"cited_themes": ["karma", "duty"],
"guided_listener_consecutive": 1,
"debug": {
"planner_reasoning": "User seeking guidance during uncertain phase, guided_listener mode appropriate",
"tool_calls": ["retrieve_scripture", "generate_response"],
"holding": false,
"closing": false,
"emotional_peak": "confusion",
"tone_register": "grounding",
"conversation_arc": "deepening",
"topic_label": "existential uncertainty",
"reflection_verdict": "pass",
"correction_applied": false,
"skipped_reflection": false,
"episodic_memory_loaded": true,
"semantic_recall_count": 3,
"fallback_chain": [],
"degraded_mode": false,
"retrieval_ran": true
}
}
}
Key Differences from V1
- Session-based: Requires
session_idfor conversation tracking - Emotional Intelligence: Classifies user emotion and adjusts response mode
- Memory Systems: Episodic (long-term) and semantic (short-term) memory
- Multi-Agent Pipeline: Scout → Planner → Tools → Generator → Reflection
- Resilience: Automatic fallback chain on agent/API failures
- Enhanced Debug: Detailed pipeline state for observability
Last updated: 2026-04-03 · Nexus v2