Spaces:
Sleeping
Model Orchestrator Service β API Documentation
Version: 1.0
Base URL: http://localhost:8090 (local) β configured via SERVICE_RUNTIME_HOST
Content-Type: application/json
Authentication
All endpoints under /api/* require a JWT Bearer token.
Authorization: Bearer <JWT_TOKEN>
The token must contain the following claims: TenantId, UserId, Email, UniqueName, FullName.
Response Format
Success
All successful responses are wrapped in a consistent envelope:
{
"data": { ... }
}
Error
{
"error_message": "Human-readable description",
"error_code": "machine.readable.code"
}
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request / validation error |
| 401 | Unauthorized β missing or invalid token |
| 500 | Internal server error |
Endpoints Overview
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /health/ready |
Readiness probe | No |
| GET | /health/live |
Liveness probe | No |
| GET | /api/room |
Get all rooms | Yes |
| PUT | /api/room/:room_id |
Update room name | Yes |
| PATCH | /api/room/:room_id |
Delete a room | Yes |
| GET | /api/room/:room_id/chat |
Get all chats in a room | Yes |
| POST | /api/chat |
Create a new chat | Yes |
| POST | /api/chat/:chat_id/retry |
Retry a failed chat | Yes |
| GET | /api/chat/:chat_id/status |
Get chat processing status | Yes |
| POST | /api/chat/:chat_id/feedback |
Submit feedback for a chat | Yes |
| GET | /api/chatbot/helper_prompt |
Get equipment helper prompts | Yes |
Health
GET /health/ready
Returns 200 Ok when the service is ready to receive traffic. No auth required.
GET /health/live
Returns 200 Ok when the service process is alive. No auth required.
Room
Rooms are conversation containers. Each room holds a list of chat exchanges belonging to a user.
GET /api/room
Get all rooms belonging to the authenticated user.
Request: No body, no query parameters.
Response 200:
{
"data": [
{
"id": "string",
"name": "string"
}
]
}
| Field | Type | Description |
|---|---|---|
id |
string | Unique room identifier |
name |
string | Display name of the room |
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 500 | modelorchestrator.room.get.error |
Failed to retrieve rooms |
PUT /api/room/:room_id
Rename an existing room.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
room_id |
string | Yes | ID of the room to update |
Request body:
{
"name": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | New name for the room |
Response 200:
{
"data": {
"room_id": "string"
}
}
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 400 | modelorchestrator.room.update.errorvalidation |
Invalid or missing request body |
| 500 | modelorchestrator.room.update.error |
Failed to update room |
PATCH /api/room/:room_id
Soft-delete a room.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
room_id |
string | Yes | ID of the room to delete |
Request body: None
Response 200:
{
"data": {
"room_id": "string"
}
}
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 500 | modelorchestrator.room.delete.error |
Failed to delete room |
GET /api/room/:room_id/chat
Get the full chat history for a specific room.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
room_id |
string | Yes | ID of the room |
Request body: None
Response 200:
{
"data": [
{
"id": "string",
"question": "any",
"answer_text": "any | null",
"status": "string",
"feedback_status": "string | null",
"feedback_reason": "string | null"
}
]
}
| Field | Type | Nullable | Description |
|---|---|---|---|
id |
string | No | Chat entry ID |
question |
any | No | The question that was submitted (can be string or object) |
answer_text |
any | Yes | The answer returned by the AI. null if still processing |
status |
string | No | Processing status of the chat. See Chat Status Values |
feedback_status |
string | Yes | Feedback given by user, if any |
feedback_reason |
string | Yes | Reason for the feedback, if any |
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 500 | modelorchestrator.room.chat.error |
Failed to retrieve room chats |
Chat
A chat represents a single questionβanswer exchange within a room. Creating a chat triggers the AI processing asynchronously β use the status endpoint to poll for completion.
POST /api/chat
Create a new chat (submit a question to the AI).
If room_id is empty, a new room will be created automatically and its ID is returned in the response.
Request body:
{
"agent": "string",
"req_plot_object": false,
"room_id": "string",
"question": "any"
}
| Field | Type | Required | Description |
|---|---|---|---|
agent |
string | Yes | Identifier of the AI agent to use |
req_plot_object |
boolean | Yes | Set true if the response should include a plot/chart object |
room_id |
string | Yes | ID of the room to post the chat in. Pass an empty string "" to auto-create a room |
question |
any | Yes | The question or prompt. Can be a plain string or a structured object depending on the agent |
Response 200:
{
"data": {
"room_id": "string",
"room_name": "string",
"chat_id": "string"
}
}
| Field | Type | Description |
|---|---|---|
room_id |
string | The room this chat belongs to (auto-generated if not provided) |
room_name |
string | Display name of the room |
chat_id |
string | ID of the newly created chat. Use this to poll status and submit feedback |
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 400 | modelorchestrator.chat.create.errorvalidation |
Invalid or missing request body |
| 500 | modelorchestrator.chat.create.error |
Failed to create chat |
POST /api/chat/:chat_id/retry
Retry a chat that failed or got stuck. Resubmits the original question.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
chat_id |
string | Yes | ID of the chat to retry |
Request body: None
Response 200:
{
"data": {
"room_id": "string",
"chat_id": "string"
}
}
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 500 | modelorchestrator.chat.retry.error |
Failed to retry chat |
GET /api/chat/:chat_id/status
Poll the processing status of a chat. Use this after creating a chat to determine when the answer is ready.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
chat_id |
string | Yes | ID of the chat |
Request body: None
Response 200:
{
"data": {
"chat_id": "string",
"status": "string"
}
}
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 500 | modelorchestrator.chat.getstatus.error |
Failed to retrieve chat status |
Chat Status Values
| Status | Description |
|---|---|
pending |
Chat has been created, waiting to be processed |
processing |
AI is currently generating a response |
completed |
Response is ready β fetch via GET /api/room/:room_id/chat |
failed |
Processing failed β use retry endpoint |
Polling recommendation: Poll every 2β3 seconds. Stop when status is
completedorfailed.
POST /api/chat/:chat_id/feedback
Submit user feedback (thumbs up/down and reason) for a completed chat.
Path parameter:
| Parameter | Type | Required | Description |
|---|---|---|---|
chat_id |
string | Yes | ID of the chat to give feedback on |
Request body:
{
"status": "string",
"reason": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | Yes | Feedback rating (e.g. "positive", "negative") |
reason |
string | Yes | Explanation for the feedback |
Response 200:
{
"data": {
"id": "string"
}
}
| Field | Type | Description |
|---|---|---|
id |
string | ID of the created feedback record |
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 400 | modelorchestrator.chat.createfeedback.errorvalidation |
Invalid or missing request body |
| 500 | modelorchestrator.chat.createfeedback.error |
Failed to submit feedback |
Chatbot
GET /api/chatbot/helper_prompt
Get a structured list of equipment suggestions to help users construct prompts. The response is a 4-level nested map: site_id β section β model β eqm_no β [equipment list].
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
topic |
string | Yes | Topic category. Must be one of the allowed values below |
year |
integer | Yes | The year to filter data by (e.g. 2024) |
Allowed topic values:
| Value | Description |
|---|---|
pa performance |
PA performance analysis |
bad actor |
Bad actor identification |
pareto |
Pareto analysis |
inspection |
Inspection data |
backlog |
Maintenance backlog |
planning |
Planning analysis |
execution |
Execution analysis |
Response 200:
{
"data": {
"<site_id>": {
"<section>": {
"<model>": {
"<eqm_no>": ["equipment_name_1", "equipment_name_2"]
}
}
}
}
}
Example:
{
"data": {
"SITE_A": {
"MECHANICAL": {
"PUMP": {
"P-001": ["P-001A", "P-001B"]
}
}
}
}
}
Error responses:
| Code | error_code |
Description |
|---|---|---|
| 400 | helper.prompt.validation.topic |
topic is missing or not one of the allowed values |
| 400 | helper.prompt.validation.year |
year query parameter is missing |
| 400 | helper.prompt.validation.year.format |
year is not a valid integer |
| 500 | helper.prompt.service.error |
Failed to retrieve helper prompt data |
Typical Frontend Flow
Below is the recommended sequence for a full chat interaction:
1. GET /api/room β fetch existing rooms for sidebar
2. POST /api/chat β submit question (use room_id="" for new room)
β returns { room_id, room_name, chat_id }
3. GET /api/chat/:chat_id/status β poll every 2β3s until status = "completed" or "failed"
4. GET /api/room/:room_id/chat β fetch full chat history including the answer
5. POST /api/chat/:chat_id/feedback β (optional) submit user rating
6. POST /api/chat/:chat_id/retry β (if status = "failed") retry
Error Code Reference
All error responses follow this format:
{
"error_message": "Human-readable description",
"error_code": "machine.readable.code"
}
Authentication Errors
These errors are returned before any endpoint logic runs, when the JWT token is missing, malformed, or invalid.
| HTTP | error_code |
error_message |
Cause |
|---|---|---|---|
| 401 | error.cred.missing |
Authorization creds missing | Authorization header not present in request |
| 401 | error.cred.incomplete |
Authorization cred incomplete | Header present but not in Bearer <token> format |
| 401 | error.cred.invalid |
Authorization cred invalid | JWT token cannot be parsed or is malformed |
| 401 | error.cred.missingAttribute |
Authorization cred attribute missing | Token is valid but missing required claims (tenantId or userId) |
| 401 | error.database.connectionfailure |
Unable to establish connection to tenant database | Service could not open a DB connection for the tenant derived from the token |
Room Errors
| HTTP | error_code |
error_message |
Endpoint | Cause |
|---|---|---|---|---|
| 500 | modelorchestrator.room.gettenant.error |
Unable to get tenant context | All room endpoints | Internal error reading tenant context from middleware |
| 400 | modelorchestrator.room.update.errorvalidation |
Unable to read input | PUT /api/room/:room_id |
Request body is missing or not valid JSON |
| 500 | modelorchestrator.room.update.error |
Unable to update room | PUT /api/room/:room_id |
Database error while updating the room |
| 500 | modelorchestrator.room.delete.error |
Unable to get room chats | PATCH /api/room/:room_id |
Database error while deleting the room |
| 500 | modelorchestrator.room.get.error |
Unable to get rooms | GET /api/room |
Database error while fetching room list |
| 500 | modelorchestrator.room.chat.error |
Unable to get room chats | GET /api/room/:room_id/chat |
Database error while fetching chat history |
Chat Errors
| HTTP | error_code |
error_message |
Endpoint | Cause |
|---|---|---|---|---|
| 500 | modelorchestrator.chat.gettenant.error |
Unable to get tenant context | All chat endpoints | Internal error reading tenant context from middleware |
| 400 | modelorchestrator.chat.create.errorvalidation |
Unable to read input | POST /api/chat |
Request body is missing or not valid JSON |
| 500 | modelorchestrator.chat.create.error |
Unable to create chat | POST /api/chat |
Database error while creating the chat record |
| 500 | modelorchestrator.chat.retry.error |
Unable to retry chat | POST /api/chat/:chat_id/retry |
Chat not found or database error during retry |
| 500 | modelorchestrator.chat.getstatus.error |
Unable to get chat status | GET /api/chat/:chat_id/status |
Database error while fetching chat status |
| 400 | modelorchestrator.chat.createfeedback.errorvalidation |
Unable to read input | POST /api/chat/:chat_id/feedback |
Request body is missing or not valid JSON |
| 500 | modelorchestrator.chat.createfeedback.error |
Unable to get chat status | POST /api/chat/:chat_id/feedback |
Database error while saving feedback |
Chatbot Errors
| HTTP | error_code |
error_message |
Endpoint | Cause |
|---|---|---|---|---|
| 500 | modelorchestrator.prompt.gettenant.error |
Unable to get tenant context | GET /api/chatbot/helper_prompt |
Internal error reading tenant context from middleware |
| 400 | helper.prompt.validation.topic |
Invalid topic provided | GET /api/chatbot/helper_prompt |
topic query param is missing or not one of the 7 allowed values |
| 400 | helper.prompt.validation.year |
Year is required | GET /api/chatbot/helper_prompt |
year query param is not provided |
| 400 | helper.prompt.validation.year.format |
Invalid year format | GET /api/chatbot/helper_prompt |
year query param is not a valid integer |
| 500 | helper.prompt.service.error |
Failed to get helper prompt | GET /api/chatbot/helper_prompt |
Database error while fetching helper prompt data |
System Errors
| HTTP | error_code |
error_message |
Cause |
|---|---|---|---|
| 500 | error.internalservererror |
Internal Server Error | Unhandled panic in the service β logged server-side with full stack trace |
CORS
CORS is enabled globally. All origins are allowed and credentials are supported.
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT, PATCH