curl --request POST \
--url https://{subdomain}.mihu.ai/api/v1/assistant/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "How many appointments do we have tomorrow?",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"user_email": "john.doe@example.com",
"callback_url": "https://example.com/hooks/mihu-assistant",
"callback_secret": "<string>",
"wait": true,
"title": "<string>"
}
'import requests
url = "https://{subdomain}.mihu.ai/api/v1/assistant/messages"
payload = {
"text": "How many appointments do we have tomorrow?",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"user_email": "john.doe@example.com",
"callback_url": "https://example.com/hooks/mihu-assistant",
"callback_secret": "<string>",
"wait": True,
"title": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: 'How many appointments do we have tomorrow?',
session_uuid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
user_email: 'john.doe@example.com',
callback_url: 'https://example.com/hooks/mihu-assistant',
callback_secret: '<string>',
wait: true,
title: '<string>'
})
};
fetch('https://{subdomain}.mihu.ai/api/v1/assistant/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.mihu.ai/api/v1/assistant/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'text' => 'How many appointments do we have tomorrow?',
'session_uuid' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'user_email' => 'john.doe@example.com',
'callback_url' => 'https://example.com/hooks/mihu-assistant',
'callback_secret' => '<string>',
'wait' => true,
'title' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{subdomain}.mihu.ai/api/v1/assistant/messages"
payload := strings.NewReader("{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{subdomain}.mihu.ai/api/v1/assistant/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{subdomain}.mihu.ai/api/v1/assistant/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"data": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "completed",
"message": {
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"role": "assistant",
"content": "<string>",
"chips": [
"<string>"
],
"tool_calls": [
{
"name": "<string>",
"error": true
}
],
"created_at": "2023-11-07T05:31:56Z"
},
"usage": {},
"cost": {
"billed_usd": 0.0142,
"debited": true
}
}
}{
"success": true,
"message": "<string>",
"data": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending"
}
}Send a message to the Mihu Assistant
Sends one message to the workspace’s Mihu Assistant — the same assistant as the /assistant page — and gets its reply back. The assistant can read and change the workspace (agents, contacts, campaigns, appointments, …) exactly as it can in the app, and each turn is billed to the workspace wallet like an in-app turn.
By default the call waits for the assistant and returns the reply in the same response (200); a turn that uses several tools can take up to a minute or two. Send wait: false to get 202 with a request_uuid immediately and receive the reply later through the callback_url given on the request, through the workspace webhook event assistant_reply (Developer → Webhooks), or by polling GET /api/v1/assistant/requests/.
Each conversation belongs to a workspace member (user_email, defaulting to the workspace owner) and is stored in that member’s assistant history exactly like one started in the app. Omit session_uuid to start a new conversation; pass one to continue an earlier conversation with its full history. Workspace API tokens only — a user JWT is refused with 403.
curl --request POST \
--url https://{subdomain}.mihu.ai/api/v1/assistant/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "How many appointments do we have tomorrow?",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"user_email": "john.doe@example.com",
"callback_url": "https://example.com/hooks/mihu-assistant",
"callback_secret": "<string>",
"wait": true,
"title": "<string>"
}
'import requests
url = "https://{subdomain}.mihu.ai/api/v1/assistant/messages"
payload = {
"text": "How many appointments do we have tomorrow?",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"user_email": "john.doe@example.com",
"callback_url": "https://example.com/hooks/mihu-assistant",
"callback_secret": "<string>",
"wait": True,
"title": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: 'How many appointments do we have tomorrow?',
session_uuid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
user_email: 'john.doe@example.com',
callback_url: 'https://example.com/hooks/mihu-assistant',
callback_secret: '<string>',
wait: true,
title: '<string>'
})
};
fetch('https://{subdomain}.mihu.ai/api/v1/assistant/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{subdomain}.mihu.ai/api/v1/assistant/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'text' => 'How many appointments do we have tomorrow?',
'session_uuid' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'user_email' => 'john.doe@example.com',
'callback_url' => 'https://example.com/hooks/mihu-assistant',
'callback_secret' => '<string>',
'wait' => true,
'title' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{subdomain}.mihu.ai/api/v1/assistant/messages"
payload := strings.NewReader("{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{subdomain}.mihu.ai/api/v1/assistant/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{subdomain}.mihu.ai/api/v1/assistant/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"text\": \"How many appointments do we have tomorrow?\",\n \"session_uuid\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"user_email\": \"john.doe@example.com\",\n \"callback_url\": \"https://example.com/hooks/mihu-assistant\",\n \"callback_secret\": \"<string>\",\n \"wait\": true,\n \"title\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"data": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "completed",
"message": {
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"role": "assistant",
"content": "<string>",
"chips": [
"<string>"
],
"tool_calls": [
{
"name": "<string>",
"error": true
}
],
"created_at": "2023-11-07T05:31:56Z"
},
"usage": {},
"cost": {
"billed_usd": 0.0142,
"debited": true
}
}
}{
"success": true,
"message": "<string>",
"data": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"session_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "pending"
}
}Authorizations
Use a Bearer token to access these API endpoints. Example: "Bearer {your-token}"
Body
The message for the assistant, in any language. It answers in the language of the message.
20000"How many appointments do we have tomorrow?"
Continue an existing assistant session (from an earlier response or GET /api/v1/assistant/sessions). Omit to start a new one.
The workspace member this conversation belongs to; defaults to the workspace owner when omitted. The session shows up in that member's assistant history in the app (Assistant → History), and a session_uuid can only be continued by the same member. Unknown email answers 404.
"john.doe@example.com"
Where to POST the reply when it is ready (JSON {event, data, timestamp}, same data shape as the 200 response). Retried up to three times. Independent of the workspace webhook, which also fires.
"https://example.com/hooks/mihu-assistant"
When set, the callback carries X-Mihu-Signature: hex HMAC-SHA256 of the raw body with this secret.
true (default) = run the turn now and return the reply in this response (up to about two minutes). false = answer 202 at once and deliver the reply later via callback_url, the assistant_reply webhook or polling.
Title for a new session; defaults to the first words of the message.
200