Sophia AI - API Documentation
CloudOverview
The Sophia API provides RESTful endpoints for managing the AI service: chat operations, document management, agent configuration, user management, API tokens, and supporting services. The API is built on RESTHeart, so most CRUD operations follow standard MongoDB-REST semantics.
Authentication
Cookie Authentication (Web Interface)
The web interface uses cookie-based authentication. Login to obtain an HttpOnly session cookie:
curl -X POST "https://api.bysophia.ai/token/cookie" \
-H "Authorization: Basic <base64-credentials>"
The response sets an rh_auth HttpOnly cookie and returns the JWT in the body (used by the SPA to decode roles client-side).
Bearer Token Authentication (API & MCP)
For programmatic access and MCP clients, use a JWT bearer token:
Authorization: Bearer <jwt-token>
API tokens are issued through the admin panel or the API token endpoint (see [_api_tokens]). For MCP clients that cannot send custom headers, the token can be passed as a ?token=<jwt> query parameter.
OAuth (MCP)
Sophia exposes the standard MCP OAuth metadata endpoints (/.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource) and supports the client_credentials grant. Claude Desktop and other OAuth-aware MCP clients re-authenticate transparently when a JWT expires. See Sophia MCP Server for client configuration details.
Chat Operations
Create Chat Message
Creates a new chat message with a prompt. Most clients submit chat documents directly to MongoDB via this endpoint; a backend interceptor turns the insert into a streamed conversation.
Endpoint: POST /chats
Query parameters:
-
agent=<agent-id>— context to use (defaults todefault)
Request body fields:
-
chatId— string, required. Stable identifier for the chat session (multiple turns share the samechatId). -
prompt— string, required. The user’s message. -
collaborative— boolean, optional. Per-message override that activates Collaborative Mode (show+ post-answerask) regardless of the agent default.
Request:
curl -X POST "https://api.bysophia.ai/chats?agent=support" \
-H "Authorization: Bearer <jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"chatId": "chat-123",
"prompt": "How do I reset my password?",
"collaborative": false
}'
The response contains the inserted document _id (interaction id). To follow the streamed answer, subscribe to the change stream below.
Subscribe to Chat Updates
Subscribe to real-time chat updates over WebSocket. The stream pushes incremental updates to the chat document as the model produces them.
Endpoint: WS /chats/_streams/subscribe
Query parameters:
-
avars={"chatId":"<chat-id>"}— chat session to subscribe to
websocat "wss://api.bysophia.ai/chats/_streams/subscribe?avars={\"chatId\":\"chat-123\"}" \
--header "Authorization: Bearer <jwt-token>"
Response stream (linear mode):
{
"fullDocument": { "_id": {"$oid": "6507f1f4..."} },
"updateDescription": {
"updatedFields": {
"chunks.0": "RESTHeart is a ",
"status": "streaming"
}
}
}
Agentic Mode Events
When the active agent has agenticMode: true and streamThinkingEvents: true, the stream includes events[] entries during the agentic phase:
| Event type | Meaning |
|---|---|
|
The model invoked a tool (e.g. |
|
Tool execution finished. Includes |
|
The agentic phase ended; the model is now composing the final answer. |
|
The primary Bedrock model errored; Sophia switched to a fallback model. Includes the failed model id and the new one. |
|
The model invoked |
Example tool start:
{
"events.0": {
"type": "tool_start",
"iteration": 1,
"toolUseId": "toolu_01ABC",
"tool": "search",
"args": {"query": "password reset", "compact": true}
}
}
Example fallback notice:
{
"events.5": {
"type": "model_fallback",
"from": "eu.anthropic.claude-sonnet-4-6",
"to": "eu.amazon.nova-lite-v1:0",
"reason": "ThrottlingException"
}
}
Artifact Share Link
Any interaction (chat document) can expose a read-only shareable link that returns only the rendered artifact step:
Endpoint: PATCH /chats/{interactionId}?chatId={chatId}
Body: {"shareToken": "<random-token>"} — sets a share token on the document.
Public read:
curl "https://api.bysophia.ai/chats/{interactionId}?shareToken={random-token}"
The response is restricted to the steps field (no auth required). Useful for sharing a generated diagram or calculator with someone outside the workspace.
Agent Management
Agents define the behaviour of Sophia for a specific knowledge domain.
List Agents
Endpoint: GET /agents
curl "https://api.bysophia.ai/agents" \
-H "Authorization: Bearer <jwt-token>"
Get Agent
Endpoint: GET /agents/{agentId}
Response (full schema):
{
"_id": "support",
"template": "You are Sophia...\n\n<documents-placeholder>",
"welcome": "Hi! How can I help?",
"hintQuestions": [
"How do I reset my password?",
"What's the refund policy?"
],
"private": false,
"tags": ["public", "support"],
"options": {
"max_tokens_to_sample": 4000,
"temperature": 0.3,
"top_k": 250,
"top_p": 1.0,
"relevantsNumCandidates": 200,
"relevantsLimit": 5,
"historyLimit": 3,
"userPromptMaxChars": 1000,
"agenticMode": true,
"maxAgentIterations": 8,
"streamThinkingEvents": true,
"extendedThinking": false,
"compactSearch": true,
"searchAndFetchPreamble": true,
"agenticContextManagement": true,
"collaborative": false,
"askDesc": null,
"showDesc": null,
"deckView": false,
"modelId": null
},
"mcp": {
"description": "Customer-facing support assistant — search FAQ and policy docs."
}
}
Create or Replace Agent
Endpoint: PUT /agents/{agentId}?wm=upsert
curl -X PUT "https://api.bysophia.ai/agents/support?wm=upsert" \
-H "Authorization: Bearer <jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"template": "You are Sophia...\n\n<documents-placeholder>",
"tags": ["support"],
"private": false,
"options": {
"agenticMode": true,
"maxAgentIterations": 8,
"compactSearch": true,
"searchAndFetchPreamble": true,
"agenticContextManagement": true
},
"mcp": { "description": "Support assistant." }
}'
Update Agent (Partial)
Endpoint: PATCH /agents/{agentId}
curl -X PATCH "https://api.bysophia.ai/agents/support" \
-H "Authorization: Bearer <jwt-token>" \
-H "Content-Type: application/json" \
-d '{"options": {"relevantsLimit": 8, "temperature": 0.2}}'
Delete Agent
Endpoint: DELETE /agents/{agentId}
Document Management
Documents are stored in MongoDB GridFS as docs.files (metadata) and docs.chunks (binary).
Upload Document
Endpoint: POST /docs.files (multipart/form-data)
Form fields:
-
file— the binary content -
metadata— JSON object with at leastfilename. Common fields:tags,pathPrefix.
curl -X POST "https://api.bysophia.ai/docs.files" \
-H "Authorization: Bearer <jwt-token>" \
-F "file=@document.pdf" \
-F 'metadata={"filename":"docs/intro/document.pdf","tags":["public","support"]}'
List Documents
Endpoint: GET /docs.files
Common parameters:
-
page=<n>— page number (1-based) -
pagesize=<n>— items per page (max ~1000) -
filter=<json>— MongoDB filter query (e.g. by filename regex or tags) -
sort=<json>— MongoDB sort spec
curl "https://api.bysophia.ai/docs.files?page=1&pagesize=20" \
-H "Authorization: Bearer <jwt-token>"
Filter by directory and tags:
http -A bearer -a "<jwt-token>" :8080/docs.files \
filter=='{"filename":{"$regex":"^docs/"},"metadata.tags":{"$in":["public"]}}'
Update Document Metadata
Endpoint: PATCH /docs.files/{fileId}
|
Note
|
For GridFS files, the PATCH body is merged into the metadata subdocument. Use root-level keys (tags, tenant, …) — not metadata.tags (which would be stored as a literal key inside metadata).
|
echo '{"tags": ["public", "support", "v2"]}' | \
http -a admin:password PATCH :8080/docs.files/{file_id}
Delete Document
Endpoint: DELETE /docs.files/{fileId}
curl -X DELETE "https://api.bysophia.ai/docs.files/6507f1f4..." \
-H "Authorization: Bearer <jwt-token>"
Deleting a document also removes all associated text segments.
Bulk delete by filter (RESTHeart 9.2+):
http -a admin:password DELETE :8080/docs.files/'*' \
filter=='{"metadata.tags":{"$in":["obsolete"]}}'
Text Segments and Vector Search
List Text Segments
Endpoint: GET /textSegments
curl "https://api.bysophia.ai/textSegments?pagesize=10" \
-H "Authorization: Bearer <jwt-token>"
The vector field is excluded from the response automatically (large array).
Semantic Search
Endpoint: GET /textSegments/_aggrs/search
Parameters:
-
prompt=<query>— the search query (URL-encoded) -
agent=<agent-id>— applies the agent’s tag filters
curl "https://api.bysophia.ai/textSegments/_aggrs/search?prompt=password%20reset&agent=support" \
-H "Authorization: Bearer <jwt-token>"
Response:
[
{
"_id": {"$oid": "..."},
"text": "To reset your password go to Settings → Security ...",
"metadata": {
"filename": "support/account.md",
"tags": ["public", "support"],
"index": 12,
"pathPrefixes": ["support/"]
},
"score": 0.91
}
]
Directory Listing
A custom service that aggregates docs.files to expose the directory tree of the knowledge base — used by the admin tree view.
Endpoint: GET /listPaths
Parameters:
-
path=<prefix>— list immediate sub-directories under this prefix. Empty / missing returns top-level dirs. -
tags=<csv>— restrict to documents carrying any of these tags -
page=<n>,pagesize=<n>— pagination
curl "https://api.bysophia.ai/listPaths?path=docs/&pagesize=20" \
-H "Authorization: Bearer <jwt-token>"
Response:
{
"data": ["docs/api/", "docs/concepts/", "docs/guides/"],
"page": 1,
"pagesize": 20,
"hasMore": false
}
Users
Standard RESTHeart-style CRUD on the users collection. Passwords are hashed automatically (bcrypt) on insert and update.
List Users
Endpoint: GET /users
curl "https://api.bysophia.ai/users" \
-H "Authorization: Bearer <jwt-token>"
Create User
Endpoint: POST /users
echo '{
"_id": "alice",
"password": "s3cret",
"roles": ["user"],
"contexts": ["support"],
"tags": []
}' | http -a admin:password POST :8080/users
Update User
Endpoint: PATCH /users/{userid}
echo '{"contexts": ["support", "internal"]}' | \
http -a admin:password PATCH :8080/users/alice
A user can change only their own password via this endpoint. Role and agent modifications require an admin account.
Delete User
Endpoint: DELETE /users/{userid}
API Tokens
Long-lived JWT tokens issued by the apiTokenCreator plugin. Each token carries username, contexts, and tags claims and is revocable.
Issue a Token
Endpoint: POST /apiTokens
echo '{
"username": "mcp-client",
"contexts": ["support"],
"tags": ["public"]
}' | http -a admin:password POST :8080/apiTokens
Response:
{
"_id": "jti-abc123",
"username": "mcp-client",
"contexts": ["support"],
"tags": ["public"],
"token": "eyJhbGciOiJIUzI1NiIs...",
"createdAt": {"$date": 1735689600000},
"revoked": false
}
|
Note
|
The token field is returned only once at creation time.
|
List Tokens
Endpoint: GET /apiTokens
Returns token metadata without JWT values.
Revoke a Token
Endpoint: PATCH /apiTokens/{jti}
echo '{"revoked": true}' | http -a admin:password PATCH :8080/apiTokens/{jti}
A revoked token is rejected on every subsequent request by a low-priority vetoer.
Delete a Token
Endpoint: DELETE /apiTokens/{jti}
Error Handling
HTTP Status Codes
| Code | Meaning |
|---|---|
|
Request successful |
|
Resource created |
|
Request successful, no content |
|
Invalid request parameters |
|
Authentication required |
|
Access denied (e.g. private agent without correct claim) |
|
Resource not found |
|
HTTP method not supported on this path |
|
Resource conflict |
|
Bedrock or app-level rate limit |
|
Server error |
Error Response Format
{
"http status code": 400,
"http status description": "Bad Request",
"message": "Missing required field: chatId"
}