Exploring the Ohwise Backend API
Introduction
In the world of AI-powered platforms, Ohwise stands out by allowing users to build, configure, and orchestrate multiple AI agents—each with their own tasks and real-time interactions. The backend API is the core that powers agent CRUD operations, task management, and live chat features.
In this post, we’ll walk through:
- Key Concepts: Agents, Tasks, and WebSocketService
- RESTful Endpoints: How to create, read, update, and delete agents/tasks
- Real-Time Messaging: Using WebSocketService to enable live chat and agent-driven events
- Sample Workflow: Creating an agent, designing its graph, adding tasks, and testing via WebSocket
By the end, you’ll have a clear understanding of how to integrate with the Ohwise backend and build dynamic AI-driven applications.
1. Core Concepts
1.1 Agents
An Agent in Ohwise is a configurable AI entity that can:
- Have metadata (name, description, publish status)
- Contain a graph: a JSON representation of tasks (nodes) and directed edges (workflows)
- Define answer_config: parameters controlling how it answers (e.g., LLM provider settings)
Example graph snippet:
{ "nodes": [ { "id": "n1", "label": "Greet User" }, { "id": "n2", "label": "Fetch Account Status" } ], "edges": [ { "from": "n1", "to": "n2" } ], "current_node_id": "n1" }
Use Cases:
- A customer support bot that first greets the user, then checks their account status.
- A tutoring agent that picks a topic, retrieves learning materials, and quizzes the student.
1.2 Tasks
A Task is a discrete piece of work within an agent’s graph. Each task includes:
- task_name: e.g., “Greet User Task”
- task_content: e.g., a prompt or script, “Hello, how can I assist you today?”
- task_config: JSON specifying provider type (e.g.,
openai
,mysql
) and details (model name, parameters)
Example task_config
:
{ "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 150 } } }
Tasks can:
- Prompt an LLM for natural-language processing
- Execute a SQL query to fetch data from a database
- Call an external HTTP API
By combining tasks into a graph, you create a workflow where the output of one task can feed into the next.
1.3 WebSocketService
For real-time communication, Ohwise offers a WebSocketService
class built on Socket.IO. Using this, your frontend can:
- Join a chat group (room)
- Send messages that optionally trigger agent execution (e.g., run current task, upstream tasks, downstream tasks, or the entire agent DAG)
- Receive intermediate reasoning events or final answers from agents
- Cleanly disconnect when leaving the chat
Key Methods:
-
startWebSocket(agents, users, threadId, chatSource, handlers)
- Connects to the server and joins a group.
- Registers callbacks (
onMessage
,onReasoning
,onAnswer
,onError
).
-
sendMessage(user_id, message, runOption, taskId?)
- Emits a
send_message
event withthread_id
,group_id
,user_id
,message_id
,content
,runOption
,taskId
. - If
runOption
is provided, triggers agent execution on the backend.
- Emits a
-
stopWebSocket()
- Leaves the group and disconnects.
This setup is perfect for building chat interfaces where an agent’s tasks are orchestrated live based on user input—helpful for customer support, tutoring, multi-agent experiments, and more.
2. RESTful Endpoints
Let’s explore the main groups of endpoints: Agents (§2.1–§2.9) and Tasks (§3.1–§3.8).
2.1 Agents CRUD
2.1.1 Create an Agent (POST /api/agent)
Request:
POST /api/agent Authorization: Bearer <access_token> Content-Type: application/json { "agent_name": "Support Bot", "agent_description": "Bot to handle customer queries", "publish_status": "private" }
Response (201):
{ "success": true, "info": "agent created", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot", "agent_description": "Bot to handle customer queries", "publish_status": "private" } }
2.1.2 Get All Agents (GET /api/agent)
Request:
GET /api/agent Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "agent list", "data": [ { "agent_id": "123e4567-e89b-12d3-a456-426614174000", "agent_name": "Agent A", "agent_description": "Description here", "publish_status": "published", "answer_config": { … } }, { "agent_id": "456e7890-e89b-12d3-a456-426614174000", "agent_name": "Agent B", "agent_description": "Another description", "publish_status": "private", "answer_config": { … } } ] }
2.1.3 Get Single Agent (GET /api/agent/{agent_id})
Request:
GET /api/agent/f47ac10b-58cc-4372-a567-0e02b2c3d479 Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "single agent info", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot", "agent_description": "Bot to handle customer queries", "publish_status": "private", "answer_config": { … } } }
2.1.4 Update Agent (PUT /api/agent/{agent_id})
Request:
PUT /api/agent/f47ac10b-58cc-4372-a567-0e02b2c3d479 Authorization: Bearer <access_token> Content-Type: application/json { "agent_name": "Support Bot v2", "agent_description": "Updated description", "publish_status": "published", "answer_config": { "model": { "parameters": { "balanced": { "top_p": 0.85, "max_tokens": 4096, "temperature": 0.7 } }, "provider_id": "Prompt", "provider_name": "Prompt", "tab_selection": "balanced", "selected_value": "Prompt" }, "provider_type": "model" } }
Response (200):
{ "success": true, "info": "agent updated successfully", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot v2", "agent_description": "Updated description", "publish_status": "published", "answer_config": { "model": { "parameters": { "balanced": { "top_p": 0.85, "max_tokens": 4096, "temperature": 0.7 } }, "provider_id": "Prompt", "provider_name": "Prompt", "tab_selection": "balanced", "selected_value": "Prompt" }, "provider_type": "model" } } }
2.1.5 Delete Agent (DELETE /api/agent/{agent_id})
Request:
DELETE /api/agent/f47ac10b-58cc-4372-a567-0e02b2c3d479 Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "agent deleted successfully", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot v2", "agent_description": "Updated description", "publish_status": "published", "answer_config": { … } } }
2.1.6 Get Agent Design (GET /api/agent/{agent_id}/design)
Request:
GET /api/agent/f47ac10b-58cc-4372-a567-0e02b2c3d479/design Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "Agent design details", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot v2", "agent_description": "Updated description", "publish_status": "published", "graph": { "nodes": [ { "id": "n1", "label": "Greet User" }, { "id": "n2", "label": "Fetch Account Status" } ], "edges": [ { "from": "n1", "to": "n2" } ], "current_node_id": "n1" } } }
2.1.7 Update Agent Design (PUT /api/agent/{agent_id}/design)
Request:
PUT /api/agent/f47ac10b-58cc-4372-a567-0e02b2c3d479/design Authorization: Bearer <access_token> Content-Type: application/json { "graph": { "nodes": [ { "id": "n1", "label": "Greet User" }, { "id": "n2", "label": "Fetch Account Status" } ], "edges": [ { "from": "n1", "to": "n2" } ], "current_node_id": "n1" } }
Response (200):
{ "success": true, "info": "Agent design updated", "data": { "agent_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agent_name": "Support Bot v2", "agent_description": "Updated description", "publish_status": "published", "graph": { "nodes": [ { "id": "n1", "label": "Greet User" }, { "id": "n2", "label": "Fetch Account Status" } ], "edges": [ { "from": "n1", "to": "n2" } ], "current_node_id": "n1" } } }
2.2 Task CRUD
2.2.1 Create Task (POST /api/task/{task_id})
Request:
POST /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e Authorization: Bearer <access_token> Content-Type: application/json { "task_name": "Greet User Task", "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 150 } } }, "task_content": "Hello, how can I assist you today?" }
Response (201):
{ "success": true, "info": "Task created", "data": { "task_id": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e", "task_name": "Greet User Task", "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 150 } } }, "task_content": "Hello, how can I assist you today?" } }
2.2.2 Get Task Details (GET /api/task/{task_id})
Request:
GET /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "Task details", "data": { "task_id": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e", "task_name": "Greet User Task", "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 150 } } }, "task_content": "Hello, how can I assist you today?" } }
2.2.3 Update Task Name (PUT /api/task/{task_id}/name)
Request:
PUT /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e/name Authorization: Bearer <access_token> Content-Type: application/json { "task_name": "Welcome Task" }
Response (200):
{ "success": true, "info": "Task name updated", "data": { "task_id": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e", "task_name": "Welcome Task", "task_config": { … }, "task_content": "Hello, how can I assist you today?" } }
2.2.4 Get Task Content (GET /api/task/{task_id}/content)
Request:
GET /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e/content Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "Task content details", "data": { "task_id": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e", "task_content": "Hello, how can I assist you today?" } }
2.2.5 Update Task Content (PUT /api/task/{task_id}/content)
Request:
PUT /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e/content Authorization: Bearer <access_token> Content-Type: application/json { "task_content": "Hi there! How can I help today?" }
Response (200):
{ "success": true, "info": "Task content updated", "data": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e" }
2.2.6 Get Task Config (GET /api/task/{task_id}/config)
Request:
GET /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e/config Authorization: Bearer <access_token>
Response (200):
{ "success": true, "info": "Task config details", "data": { "task_id": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e", "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 150 } } } } }
2.2.7 Update Task Config (PUT /api/task/{task_id}/config)
Request:
PUT /api/task/5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e/config Authorization: Bearer <access_token> Content-Type: application/json { "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4o", "parameters": { "top_p": 0.9, "max_tokens": 200, "temperature": 0.2 } } } }
Response (200):
{ "success": true, "info": "Task config updated", "data": "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e" }
2.3 Task Error Responses
- 404 Not Found: Requested task does not exist.
- 500 Internal Server Error: Unexpected server error.
3. WebSocketService in Practice
Here’s how you can integrate real-time chat and agent actions:
-
Initialize WebSocket Connection
webSocketService.startWebSocket( ["f47ac10b-58cc-4372-a567-0e02b2c3d479"], // agent IDs ["user123", "user456"], // user IDs "threadABC", // thread ID 1, // chatSource = 1 (chat) { onMessage: (msg) => console.log("Received chat:", msg), onReasoning: (reason) => console.log("Agent reasoning:", reason), onAnswer: (ans) => console.log("Agent answer:", ans), onError: (err) => console.error("WebSocket error:", err), } );
-
Send a Chat Message (Triggering Agent Execution)
webSocketService.sendMessage( "user123", "What is the status of my order?", "current", // run only the current task "5e1f2a9c-3d4f-4a5d-b6e7-8f9a0b1c2d3e" // ID of "Fetch Account Status" task );
-
Receive Intermediate Reasoning and Final Answer
- onReasoning callback fires as the agent processes steps (e.g., fetching data).
- onAnswer callback fires when the agent returns a final response.
-
Stop WebSocket When Done
webSocketService.stopWebSocket();
4. Putting It All Together: Sample Workflow
Imagine you want to build a “Customer Support Bot” that:
- Greets the user.
- Retrieves the user’s account status from a database.
- Returns a personalized message based on that status.
4.1 Step 1: Create the Agent
POST /api/agent Authorization: Bearer <access_token> Content-Type: application/json { "agent_name": "Customer Support Bot", "agent_description": "Handles user greetings and account lookups", "publish_status": "private" }
Response:
{ "success": true, "info": "agent created", "data": { "agent_id": "a1b2c3d4-5678-90ab-cdef-1234567890ab", "agent_name": "Customer Support Bot", "agent_description": "Handles user greetings and account lookups", "publish_status": "private" } }
4.2 Step 2: Create Tasks
4.2.1 Greet User Task
POST /api/task/11111111-2222-3333-4444-555555555555 Authorization: Bearer <access_token> Content-Type: application/json { "task_name": "Greet User Task", "task_config": { "provider_type": "openai", "provider_details": { "model": "gpt-4", "parameters": { "max_tokens": 50 } } }, "task_content": "Hello {{user_name}}, welcome back! How can I assist you today?" }
Response:
{ "success": true, "info": "Task created", "data": { "task_id": "11111111-2222-3333-4444-555555555555", "task_name": "Greet User Task", "task_config": { … }, "task_content": "Hello {{user_name}}, welcome back! How can I assist you today?" } }
4.2.2 Fetch Account Status Task
POST /api/task/66666666-7777-8888-9999-000000000000 Authorization: Bearer <access_token> Content-Type: application/json { "task_name": "Fetch Account Status Task", "task_config": { "provider_type": "postgresql", "provider_details": { "connection_string": "<DB_CONN_STRING>", "query": "SELECT status FROM accounts WHERE user_id = '{{user_id}}';" } }, "task_content": "" // Content not needed for a pure SQL task }
Response:
{ "success": true, "info": "Task created", "data": { "task_id": "66666666-7777-8888-9999-000000000000", "task_name": "Fetch Account Status Task", "task_config": { "provider_type": "postgresql", "provider_details": { "connection_string": "<DB_CONN_STRING>", "query": "SELECT status FROM accounts WHERE user_id = '{{user_id}}';" } }, "task_content": "" } }
4.3 Step 3: Design the Agent Graph
PUT /api/agent/a1b2c3d4-5678-90ab-cdef-1234567890ab/design Authorization: Bearer <access_token> Content-Type: application/json { "graph": { "nodes": [ { "id": "11111111-2222-3333-4444-555555555555", "label": "Greet User" }, { "id": "66666666-7777-8888-9999-000000000000", "label": "Fetch Account Status" } ], "edges": [ { "from": "11111111-2222-3333-4444-555555555555", "to": "66666666-7777-8888-9999-000000000000" } ], "current_node_id": "11111111-2222-3333-4444-555555555555" } }
Response:
{ "success": true, "info": "Agent design updated", "data": { "agent_id": "a1b2c3d4-5678-90ab-cdef-1234567890ab", "agent_name": "Customer Support Bot", "agent_description": "Handles user greetings and account lookups", "publish_status": "private", "graph": { "nodes": [ { "id": "11111111-2222-3333-4444-555555555555", "label": "Greet User" }, { "id": "66666666-7777-8888-9999-000000000000", "label": "Fetch Account Status" } ], "edges": [ { "from": "11111111-2222-3333-4444-555555555555", "to": "66666666-7777-8888-9999-000000000000" } ], "current_node_id": "11111111-2222-3333-4444-555555555555" } } }
4.4 Step 4: Test via WebSocket
-
Connect to WebSocket:
webSocketService.startWebSocket( ["a1b2c3d4-5678-90ab-cdef-1234567890ab"], // agent ID ["user123"], // single user "thread1", // thread ID 1, // chatSource = 1 (chat) { onMessage: (msg) => console.log("Chat:", msg), onReasoning: (reason) => console.log("Reasoning:", reason), onAnswer: (ans) => console.log("Answer:", ans), onError: (err) => console.error("Error:", err), } );
-
Send Message to Run Current Task:
webSocketService.sendMessage( "user123", "Hello, I'm user123!", "current", "11111111-2222-3333-4444-555555555555" );
- This triggers the “Greet User Task” first.
- Once that completes, the backend sees the graph edge → “Fetch Account Status Task.”
- Backend executes the SQL query with
{{user_id}} = "user123"
. - Reasoning events might fire as partial results arrive, followed by a final answer with combined output (e.g., “Hello user123! Your account status is Active.”).
-
Disconnect once done:
webSocketService.stopWebSocket();
5. Conclusion
The Ohwise Backend API empowers developers to:
- Manage AI Agents: Create, retrieve, update, and delete agents.
- Design Workflows: Define directed graphs of tasks that represent complex multi-step processes.
- Configure Tasks: Attach models, databases, or APIs to each task, customizing parameters, queries, or prompts.
- Real-Time Interaction: Leverage WebSocketService to build chat interfaces where agents can reason step-by-step and return final answers.
With this API, you can rapidly build sophisticated AI-driven applications—customer support bots, tutoring systems, business intelligence agents, and more—while maintaining flexibility, scalability, and real-time capabilities.
Continue reading
More projectJoin the Discussion
Share your thoughts and insights about this project.