Edit Page

Sophia AI - API Documentation

Cloud

Overview

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

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 to default)

Request body fields:

  • chatId — string, required. Stable identifier for the chat session (multiple turns share the same chatId).

  • prompt — string, required. The user’s message.

  • collaborative — boolean, optional. Per-message override that activates Collaborative Mode (show + post-answer ask) 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

tool_start

The model invoked a tool (e.g. search). Includes tool, iteration, args.

tool_result

Tool execution finished. Includes resultSummary, durationMs.

text_start

The agentic phase ended; the model is now composing the final answer.

model_fallback

The primary Bedrock model errored; Sophia switched to a fallback model. Includes the failed model id and the new one.

render_step

The model invoked show to inject an interactive HTML artifact in the chat.

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"
  }
}

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 least filename. 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"]}}'

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).

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

200 OK

Request successful

201 Created

Resource created

204 No Content

Request successful, no content

400 Bad Request

Invalid request parameters

401 Unauthorized

Authentication required

403 Forbidden

Access denied (e.g. private agent without correct claim)

404 Not Found

Resource not found

405 Method Not Allowed

HTTP method not supported on this path

409 Conflict

Resource conflict

429 Too Many Requests

Bedrock or app-level rate limit

500 Internal Server Error

Server error

Error Response Format

{
  "http status code": 400,
  "http status description": "Bad Request",
  "message": "Missing required field: chatId"
}