curl --request POST \
--url https://{subdomain}.mihu.ai/api/v1/workspace/users \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Jane",
"surname": "Doe",
"email": "jane@acme.com",
"password": "S3cret-passphrase",
"roles": [
"loop_agent"
]
}
'import requests
url = "https://{subdomain}.mihu.ai/api/v1/workspace/users"
payload = {
"name": "Jane",
"surname": "Doe",
"email": "jane@acme.com",
"password": "S3cret-passphrase",
"roles": ["loop_agent"]
}
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({
name: 'Jane',
surname: 'Doe',
email: 'jane@acme.com',
password: 'S3cret-passphrase',
roles: ['loop_agent']
})
};
fetch('https://{subdomain}.mihu.ai/api/v1/workspace/users', 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/workspace/users",
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([
'name' => 'Jane',
'surname' => 'Doe',
'email' => 'jane@acme.com',
'password' => 'S3cret-passphrase',
'roles' => [
'loop_agent'
]
]),
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/workspace/users"
payload := strings.NewReader("{\n \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\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/workspace/users")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{subdomain}.mihu.ai/api/v1/workspace/users")
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 \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Workspace member created",
"data": {
"email": "jane@acme.com",
"name": "Jane",
"surname": "Doe",
"full_name": "Jane Doe",
"status": "active",
"is_workspace_owner": false,
"timezone": "Europe/Istanbul",
"language_code": "tr",
"roles": [
{
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"key": "loop_agent",
"name": "Loop Agent"
}
],
"role_scopes": [
"<string>"
],
"direct_scopes": [
"<string>"
],
"effective_scopes": [
"<string>"
],
"created_at": "2023-11-07T05:31:56Z"
}
}{
"success": false,
"message": "This email address is already registered.",
"data": []
}Add a member directly
Creates the member immediately with the password you set — no invitation, no acceptance step. Use it when you provision accounts yourself; use POST /api/v1/workspace/invitations when the person should set their own password. The member is created in the workspace with exactly the roles and scopes named here, so at least one of them is required. An e-mail that already belongs to a user (in this or any other workspace) is refused.
curl --request POST \
--url https://{subdomain}.mihu.ai/api/v1/workspace/users \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Jane",
"surname": "Doe",
"email": "jane@acme.com",
"password": "S3cret-passphrase",
"roles": [
"loop_agent"
]
}
'import requests
url = "https://{subdomain}.mihu.ai/api/v1/workspace/users"
payload = {
"name": "Jane",
"surname": "Doe",
"email": "jane@acme.com",
"password": "S3cret-passphrase",
"roles": ["loop_agent"]
}
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({
name: 'Jane',
surname: 'Doe',
email: 'jane@acme.com',
password: 'S3cret-passphrase',
roles: ['loop_agent']
})
};
fetch('https://{subdomain}.mihu.ai/api/v1/workspace/users', 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/workspace/users",
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([
'name' => 'Jane',
'surname' => 'Doe',
'email' => 'jane@acme.com',
'password' => 'S3cret-passphrase',
'roles' => [
'loop_agent'
]
]),
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/workspace/users"
payload := strings.NewReader("{\n \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\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/workspace/users")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{subdomain}.mihu.ai/api/v1/workspace/users")
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 \"name\": \"Jane\",\n \"surname\": \"Doe\",\n \"email\": \"jane@acme.com\",\n \"password\": \"S3cret-passphrase\",\n \"roles\": [\n \"loop_agent\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Workspace member created",
"data": {
"email": "jane@acme.com",
"name": "Jane",
"surname": "Doe",
"full_name": "Jane Doe",
"status": "active",
"is_workspace_owner": false,
"timezone": "Europe/Istanbul",
"language_code": "tr",
"roles": [
{
"uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"key": "loop_agent",
"name": "Loop Agent"
}
],
"role_scopes": [
"<string>"
],
"direct_scopes": [
"<string>"
],
"effective_scopes": [
"<string>"
],
"created_at": "2023-11-07T05:31:56Z"
}
}{
"success": false,
"message": "This email address is already registered.",
"data": []
}Authorizations
Use a Bearer token to access these API endpoints. Example: "Bearer {your-token}"
Body
"Jane"
"jane@acme.com"
At least 8 characters. The member can change it later.
8"S3cret-passphrase"
"Doe"
Defaults to the workspace timezone.
"Europe/Istanbul"
Defaults to the workspace language.
"tr"
Defaults to active. An inactive or blocked member cannot sign in.
active, inactive, blocked "active"
Workspace role keys or uuids.
["loop_agent"]
Extra scope keys on top of the roles.
["loop.calls.place"]