Introduction
This documentation aims to provide all the information you need to work with our API.
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {ACCESS_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Token based authentication
You can retrieve your access token by calling api/login endpoint.
Access tokens are valid 7 days, then expire. You can obtain new access token with expiring access token by calling /api/token/refresh. You can only refresh still valid tokens, otherwise new request to api/login will be required.
Cookie based authentication
You can also authenticate using cookie-based sessions. Before calling any other endpoints you have to obtain XSRF cookie by hitting /sanctum/csrf-cookie endpoint.
In return you receive XSRF-TOKEN cookie, which content you have to attach to each request as X-XSRF-TOKEN header.
Then call /login endpoint. When your authenticated session is created, call any endpoint using X-XSRF-TOKEN header.
Multi-Factor Authorization (MFA)
User can protect its account setting up the MFA as email or one-time passwords (OTP).
If mfa_enabled is set to 1 and mfa_method is set to any of email or otp values,
user will have to use preferred method as second factor on login.
If mfa_method is email, API will automatically send MFA code to user's email inbox.
Most of API endpoints are secured with additional layer and cannot be properly called without this second-factor authorization done.
Instead of endpoint response API will reply with message "MFA is required for this request." and HTTP code 401 Unauthorized.
That means user did not successfully authorized itself with second-factor.
Multi-Factor Authorization (MFA) - Remember Session
The user has the option to remember their device, which means they won't have to enter the MFA code for 30 days.
If using a Token based authentication, you need to add a header named X-MFA-Session-Token with the value {mfa_token} obtained from the /verify endpoint.
Appendix A. Laravel validation rules
List of validation codes returned for Laravel's built-in validation rules:
1, true, "yes" or "on".other field equals to value. Accepted values are the same as in MUST_BE_ACCEPTED.dns_get_record PHP function.date.date.date.date.min and max.min and max KB.min and max.min and max elements.true, false, 1, 0, "1" and "0".{field}_confirmation.strtotime PHP function.date.other.digits digits.min and max digits.value.value.value KB.value.value elements.value.value KB.value.value elements.values list.other field values.value.value KB.value.value elements.value.value KB.value.value elements.value.value KB.value.value elements.Note that the rule uses file extensions, but Laravel internally verifies the actual MIME type using the file's contents.
value.value KB.value.value elements.value.values list. This is the opposite of MUST_BE_IN rule.Field is considered empty if its value is null, an empty string, an empty array or a file input with no file uploaded.
other field is equal to value.other field is equal to value.values are present and not empty.values are present and not empty.values are not present or empty.values are not present or empty.other field is equal to value.other field is equal to value.other field can't be present at the same time.other field.size.size KB.size.size elements.value.timezone_identifiers_list PHP function.More detailed information about validation rules can be found in Laravel documentation.
Appendix B. Custom validation rules
List of custom validation rules messages:
maxmax.max_sizemax_size KB./api/timezones endpoint.RULES:PORTRAIT_VIDEO_RULE:NOT_PORTRAIT
UNREADABLE_VIDEO if the video file could not be read, or NOT_PORTRAIT if it is landscape or square.content_typeRULES:URL_EXISTS_RULE:NOT_FOUND
If
content_type was specified, the rule also verifies the returned Content-Type header. If it doesn't match, the error code will include EXPECTED_CONTENT_TYPE:content_type.Otherwise, it only checks the status code and returns
NOT_FOUND if it's not 200.Fails if HTTP code is not 200 or the Content-Type doesn't match the expected value (if specified).
Acadle
Endpoints related to Acadle integration
Acadle SSO
requires authentication
Creates the SSO authorization link. The link expires after 60 seconds, but can be re-generated without any limits.
Example request:
curl --request POST \
"http://localhost:8000/api/acadle/sso" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/acadle/sso"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"sso_url": "https://adp.acadle.com/sso/authenticate/callback?ssoToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3MzczNzU3OTksImV4cCI6MTczNzM3NTg1OSwiZmlyc3RuYW1lIjoiVG9tIiwibGFzdG5hbWUiOiJTbWl0aCIsImVtYWlsIjoidGVzdEBleGFtcGxlLmNvbSIsInVzZXJuYW1lIjpudWxsLCJ0aW1lem9uZSI6IlVUQyJ9.VzE2q6V53bdYJM7aB6CWWxDqcxF4gpdiEF80dD9j-5k",
"sso_expires": 1737375859
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SSO:INSUFFICIENT_PERMISSION"
}
Example response (403, Survey required):
{
"message": "Completing the survey is required to proceed to Acadle",
"code": "ACADLE:SSO:SURVEY_REQUIRED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check Acadle survey status
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/acadle/survey/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/acadle/survey/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"survey_sent": false,
"survey_id": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SURVEY_STATUS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Acadle survey data
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/acadle/survey" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/acadle/survey"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (201):
{
"id": 1,
"user_id": 301,
"cpo_number": "3189",
"country": "Brazil",
"medical_training": "physician",
"myo_exp_zeus": "0",
"has_demo_hand_access": 0,
"wants_demo_hand": 1,
"myo_exp_covvi": 1,
"myo_exp_fillauer": 0,
"myo_exp_ossur": 0,
"myo_exp_ottobock": 0,
"myo_exp_steeper": 0,
"myo_exp_taska": 1,
"myo_exp_vincent": 0,
"myo_exp_pattern_recognition": 1,
"myo_exp_other": "Quas saepe ea possimus ea quo distinctio vitae.",
"partial_hand_protheses": "4",
"below_elbow_protheses_single_action": "3",
"below_elbow_protheses_multi_action": "0",
"above_elbow_protheses": "1",
"shoulder_protheses": "3",
"zeus_components_description": "Eum nemo et laboriosam doloribus animi dicta nisi.",
"contact_name": "Velva",
"contact_surname": "Lemke",
"company_name": "Sipes Ltd",
"street": "9297 Koepp Brooks Apt. 118",
"city": "Nelsonside",
"postal_code": "64119",
"email": "nelson80@langworth.com",
"phone": "432-644-7877",
"phone_country": "jo",
"device_side": "L",
"created_at": "2026-09-22T11:26:51.000000Z",
"updated_at": "2026-09-22T11:26:51.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SURVEY_RESULTS:INSUFFICIENT_PERMISSION"
}
Example response (404, Survey not found):
{
"message": "Survey not found",
"code": "ACADLE:SURVEY_RESULTS:SURVEY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Survey ID.
user_id
integer
Associated user ID.
cpo_number
string
CPO number.
country
string
Country code.
medical_training
string
Medical training level.
myo_exp_zeus
string
Zeus myo experience.
myo_exp_covvi
string
Covvi myo experience.
myo_exp_fillauer
string
Fillauer myo experience.
myo_exp_ossur
string
Ossur myo experience.
myo_exp_ottobock
string
Ottobock myo experience.
myo_exp_steeper
string
Steeper myo experience.
myo_exp_taska
string
Taska myo experience.
myo_exp_vincent
string
Vincent myo experience.
myo_exp_pattern_recognition
string
Pattern recognition myo experience.
myo_exp_other
string
Other myo experience.
has_demo_hand_access
boolean
Whether the user has demo hand access.
wants_demo_hand
boolean
Whether the user wants a demo hand.
partial_hand_protheses
string
Partial hand prostheses experience.
below_elbow_protheses_single_action
string
Below elbow single action prostheses experience.
below_elbow_protheses_multi_action
string
Below elbow multi-action prostheses experience.
above_elbow_protheses
string
Above elbow prostheses experience.
shoulder_protheses
string
Shoulder prostheses experience.
zeus_components_description
string
Zeus components description.
contact_name
string
Contact first name.
contact_surname
string
Contact last name.
company_name
string
Company name.
street
string
Street address.
city
string
City.
postal_code
string
Postal code.
email
string
Contact email.
phone
string
Contact phone.
phone_country
string
Phone country code.
device_side
string
Device side.
Must be one of:LR
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Get Acadle survey data (SuperAdmin)
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/acadle/survey/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/acadle/survey/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (201):
{
"id": 2,
"user_id": 302,
"cpo_number": "796236",
"country": "Ecuador",
"medical_training": "physician",
"myo_exp_zeus": "1",
"has_demo_hand_access": 0,
"wants_demo_hand": 0,
"myo_exp_covvi": 0,
"myo_exp_fillauer": 1,
"myo_exp_ossur": 1,
"myo_exp_ottobock": 0,
"myo_exp_steeper": 1,
"myo_exp_taska": 1,
"myo_exp_vincent": 0,
"myo_exp_pattern_recognition": 1,
"myo_exp_other": "Enim inventore totam nihil commodi suscipit.",
"partial_hand_protheses": "1",
"below_elbow_protheses_single_action": "5",
"below_elbow_protheses_multi_action": "2",
"above_elbow_protheses": "3",
"shoulder_protheses": "2",
"zeus_components_description": "Dolorem maxime eos facere quia.",
"contact_name": "Jed",
"contact_surname": "Harvey",
"company_name": "Cremin Inc",
"street": "93203 Jude Park",
"city": "East Brendenview",
"postal_code": "05908-5749",
"email": "aubree.hagenes@kovacek.com",
"phone": "253.748.2706",
"phone_country": "gy",
"device_side": "L",
"created_at": "2026-09-22T11:26:52.000000Z",
"updated_at": "2026-09-22T11:26:52.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SURVEY_RESULTS_ADMIN:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "ACADLE:SURVEY_RESULTS_ADMIN:USER_NOT_FOUND"
}
Example response (404, Survey not found):
{
"message": "Survey not found",
"code": "ACADLE:SURVEY_RESULTS_ADMIN:SURVEY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Survey ID.
user_id
integer
Associated user ID.
cpo_number
string
CPO number.
country
string
Country code.
medical_training
string
Medical training level.
myo_exp_zeus
string
Zeus myo experience.
myo_exp_covvi
string
Covvi myo experience.
myo_exp_fillauer
string
Fillauer myo experience.
myo_exp_ossur
string
Ossur myo experience.
myo_exp_ottobock
string
Ottobock myo experience.
myo_exp_steeper
string
Steeper myo experience.
myo_exp_taska
string
Taska myo experience.
myo_exp_vincent
string
Vincent myo experience.
myo_exp_pattern_recognition
string
Pattern recognition myo experience.
myo_exp_other
string
Other myo experience.
has_demo_hand_access
boolean
Whether the user has demo hand access.
wants_demo_hand
boolean
Whether the user wants a demo hand.
partial_hand_protheses
string
Partial hand prostheses experience.
below_elbow_protheses_single_action
string
Below elbow single action prostheses experience.
below_elbow_protheses_multi_action
string
Below elbow multi-action prostheses experience.
above_elbow_protheses
string
Above elbow prostheses experience.
shoulder_protheses
string
Shoulder prostheses experience.
zeus_components_description
string
Zeus components description.
contact_name
string
Contact first name.
contact_surname
string
Contact last name.
company_name
string
Company name.
street
string
Street address.
city
string
City.
postal_code
string
Postal code.
email
string
Contact email.
phone
string
Contact phone.
phone_country
string
Phone country code.
device_side
string
Device side.
Must be one of:LR
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
List all Acadle surveys (SuperAdmin)
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/acadle/surveys?search=john" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/acadle/surveys"
);
const params = {
"search": "john",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 3,
"user_id": 303,
"cpo_number": "1811",
"country": "India",
"medical_training": "clinician",
"myo_exp_zeus": "0",
"has_demo_hand_access": 0,
"wants_demo_hand": 0,
"myo_exp_covvi": 1,
"myo_exp_fillauer": 1,
"myo_exp_ossur": 0,
"myo_exp_ottobock": 1,
"myo_exp_steeper": 1,
"myo_exp_taska": 0,
"myo_exp_vincent": 0,
"myo_exp_pattern_recognition": 1,
"myo_exp_other": "Atque consequatur corrupti error error illum corrupti.",
"partial_hand_protheses": "0",
"below_elbow_protheses_single_action": "0",
"below_elbow_protheses_multi_action": "2",
"above_elbow_protheses": "3",
"shoulder_protheses": "3",
"zeus_components_description": "Consequatur nihil aliquid sapiente magnam ab nihil.",
"contact_name": "Erica",
"contact_surname": "Corwin",
"company_name": "Crona-Schaefer",
"street": "75607 Jacobson Mount Suite 133",
"city": "East Lou",
"postal_code": "39273-7572",
"email": "floyd43@hettinger.net",
"phone": "272-879-2550",
"phone_country": "lv",
"device_side": "L",
"created_at": "2026-09-22T11:26:53.000000Z",
"updated_at": "2026-09-22T11:26:53.000000Z"
},
{
"id": 4,
"user_id": 304,
"cpo_number": "22825479",
"country": "Iran",
"medical_training": "biomedical_engineer",
"myo_exp_zeus": "1",
"has_demo_hand_access": 1,
"wants_demo_hand": 0,
"myo_exp_covvi": 1,
"myo_exp_fillauer": 1,
"myo_exp_ossur": 1,
"myo_exp_ottobock": 1,
"myo_exp_steeper": 1,
"myo_exp_taska": 0,
"myo_exp_vincent": 0,
"myo_exp_pattern_recognition": 0,
"myo_exp_other": "Animi ea facere totam.",
"partial_hand_protheses": "4",
"below_elbow_protheses_single_action": "0",
"below_elbow_protheses_multi_action": "4",
"above_elbow_protheses": "0",
"shoulder_protheses": "4",
"zeus_components_description": "Alias quia fugit necessitatibus nemo dolore possimus magni.",
"contact_name": "Kendrick",
"contact_surname": "Kohler",
"company_name": "Miller, Batz and Roob",
"street": "273 Pamela Roads",
"city": "Leanneshire",
"postal_code": "30455",
"email": "schuyler.larkin@lebsack.org",
"phone": "(469) 430-5479",
"phone_country": "gn",
"device_side": "L",
"created_at": "2026-09-22T11:26:55.000000Z",
"updated_at": "2026-09-22T11:26:55.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SURVEYS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Survey ID.
user_id
integer
Associated user ID.
cpo_number
string
CPO number.
country
string
Country code.
medical_training
string
Medical training level.
myo_exp_zeus
string
Zeus myo experience.
myo_exp_covvi
string
Covvi myo experience.
myo_exp_fillauer
string
Fillauer myo experience.
myo_exp_ossur
string
Ossur myo experience.
myo_exp_ottobock
string
Ottobock myo experience.
myo_exp_steeper
string
Steeper myo experience.
myo_exp_taska
string
Taska myo experience.
myo_exp_vincent
string
Vincent myo experience.
myo_exp_pattern_recognition
string
Pattern recognition myo experience.
myo_exp_other
string
Other myo experience.
has_demo_hand_access
boolean
Whether the user has demo hand access.
wants_demo_hand
boolean
Whether the user wants a demo hand.
partial_hand_protheses
string
Partial hand prostheses experience.
below_elbow_protheses_single_action
string
Below elbow single action prostheses experience.
below_elbow_protheses_multi_action
string
Below elbow multi-action prostheses experience.
above_elbow_protheses
string
Above elbow prostheses experience.
shoulder_protheses
string
Shoulder prostheses experience.
zeus_components_description
string
Zeus components description.
contact_name
string
Contact first name.
contact_surname
string
Contact last name.
company_name
string
Company name.
street
string
Street address.
city
string
City.
postal_code
string
Postal code.
email
string
Contact email.
phone
string
Contact phone.
phone_country
string
Phone country code.
device_side
string
Device side.
Must be one of:LR
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Send Acadle survey
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/acadle/survey" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"cpo_number\": 5049,
\"country\": \"Libyan Arab Jamahiriya\",
\"medical_training\": \"physician\",
\"myo_exp_zeus\": false,
\"myo_exp_covvi\": false,
\"myo_exp_fillauer\": false,
\"myo_exp_ossur\": false,
\"myo_exp_ottobock\": false,
\"myo_exp_steeper\": false,
\"myo_exp_taska\": false,
\"myo_exp_vincent\": false,
\"myo_exp_pattern_recognition\": false,
\"myo_exp_other\": \"Ut aperiam nihil ut in rerum aut enim.\",
\"has_demo_hand_access\": false,
\"wants_demo_hand\": false,
\"partial_hand_protheses\": \"1-5\",
\"below_elbow_protheses_single_action\": \"1-5\",
\"below_elbow_protheses_multi_action\": \"5-10\",
\"above_elbow_protheses\": \"50+\",
\"shoulder_protheses\": \"1-5\",
\"zeus_components_description\": \"Aut saepe placeat libero labore sit animi ullam.\",
\"contact_name\": \"Lenore\",
\"company_name\": \"Quigley PLC\",
\"street\": \"9699 Wanda Trace Suite 439\",
\"city\": \"Aliceside\",
\"postal_code\": \"70554-0222\",
\"email\": \"hadley95@bechtelar.com\",
\"phone\": \"1-740-782-3798\",
\"phone_country\": \"IE\",
\"device_side\": \"R\"
}"
const url = new URL(
"http://localhost:8000/api/acadle/survey"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"cpo_number": 5049,
"country": "Libyan Arab Jamahiriya",
"medical_training": "physician",
"myo_exp_zeus": false,
"myo_exp_covvi": false,
"myo_exp_fillauer": false,
"myo_exp_ossur": false,
"myo_exp_ottobock": false,
"myo_exp_steeper": false,
"myo_exp_taska": false,
"myo_exp_vincent": false,
"myo_exp_pattern_recognition": false,
"myo_exp_other": "Ut aperiam nihil ut in rerum aut enim.",
"has_demo_hand_access": false,
"wants_demo_hand": false,
"partial_hand_protheses": "1-5",
"below_elbow_protheses_single_action": "1-5",
"below_elbow_protheses_multi_action": "5-10",
"above_elbow_protheses": "50+",
"shoulder_protheses": "1-5",
"zeus_components_description": "Aut saepe placeat libero labore sit animi ullam.",
"contact_name": "Lenore",
"company_name": "Quigley PLC",
"street": "9699 Wanda Trace Suite 439",
"city": "Aliceside",
"postal_code": "70554-0222",
"email": "hadley95@bechtelar.com",
"phone": "1-740-782-3798",
"phone_country": "IE",
"device_side": "R"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 5,
"user_id": 305,
"cpo_number": "2880",
"country": "Cuba",
"medical_training": "physiotherapist",
"myo_exp_zeus": "1",
"has_demo_hand_access": 0,
"wants_demo_hand": 0,
"myo_exp_covvi": 0,
"myo_exp_fillauer": 1,
"myo_exp_ossur": 0,
"myo_exp_ottobock": 0,
"myo_exp_steeper": 1,
"myo_exp_taska": 0,
"myo_exp_vincent": 1,
"myo_exp_pattern_recognition": 1,
"myo_exp_other": "Eum minus occaecati quia aliquam quod assumenda ut.",
"partial_hand_protheses": "5",
"below_elbow_protheses_single_action": "4",
"below_elbow_protheses_multi_action": "4",
"above_elbow_protheses": "3",
"shoulder_protheses": "3",
"zeus_components_description": "Sapiente libero cumque maiores quam.",
"contact_name": "Emerald",
"contact_surname": "Williamson",
"company_name": "Haley, Reynolds and Bins",
"street": "145 Kulas Manor",
"city": "Schuppefort",
"postal_code": "28713-6944",
"email": "jacobs.dixie@kling.com",
"phone": "551.919.5631",
"phone_country": "im",
"device_side": "L",
"created_at": "2026-09-22T11:26:56.000000Z",
"updated_at": "2026-09-22T11:26:56.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use Acadle",
"code": "ACADLE:SURVEY_SEND:INSUFFICIENT_PERMISSION"
}
Example response (403, Survey already sent):
{
"message": "Survey already sent",
"code": "ACADLE:SURVEY_SEND:SURVEY_ALREADY_SENT"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Survey ID.
user_id
integer
Associated user ID.
cpo_number
string
CPO number.
country
string
Country code.
medical_training
string
Medical training level.
myo_exp_zeus
string
Zeus myo experience.
myo_exp_covvi
string
Covvi myo experience.
myo_exp_fillauer
string
Fillauer myo experience.
myo_exp_ossur
string
Ossur myo experience.
myo_exp_ottobock
string
Ottobock myo experience.
myo_exp_steeper
string
Steeper myo experience.
myo_exp_taska
string
Taska myo experience.
myo_exp_vincent
string
Vincent myo experience.
myo_exp_pattern_recognition
string
Pattern recognition myo experience.
myo_exp_other
string
Other myo experience.
has_demo_hand_access
boolean
Whether the user has demo hand access.
wants_demo_hand
boolean
Whether the user wants a demo hand.
partial_hand_protheses
string
Partial hand prostheses experience.
below_elbow_protheses_single_action
string
Below elbow single action prostheses experience.
below_elbow_protheses_multi_action
string
Below elbow multi-action prostheses experience.
above_elbow_protheses
string
Above elbow prostheses experience.
shoulder_protheses
string
Shoulder prostheses experience.
zeus_components_description
string
Zeus components description.
contact_name
string
Contact first name.
contact_surname
string
Contact last name.
company_name
string
Company name.
street
string
Street address.
city
string
City.
postal_code
string
Postal code.
email
string
Contact email.
phone
string
Contact phone.
phone_country
string
Phone country code.
device_side
string
Device side.
Must be one of:LR
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Activation codes
API endpoints for activation codes
Get activation codes
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/activation-codes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"code": "E9H6Z5",
"created_by": 41,
"used_by": 42,
"used_at": null,
"active": 0,
"created_at": "2026-09-22T11:24:38.000000Z",
"updated_at": "2026-09-22T11:24:38.000000Z"
},
{
"id": 2,
"code": "MW8VS3",
"created_by": 43,
"used_by": 44,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:39.000000Z",
"updated_at": "2026-09-22T11:24:39.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get active activation codes
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/activation-codes/active" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes/active"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 3,
"code": "54J2TD",
"created_by": 45,
"used_by": 46,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:40.000000Z",
"updated_at": "2026-09-22T11:24:40.000000Z"
},
{
"id": 4,
"code": "LLKBSQ",
"created_by": 47,
"used_by": 48,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:ACTIVE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Find activation code
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/activation-codes/find/voluptas" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes/find/voluptas"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 5,
"code": "5NHMN3",
"created_by": null,
"used_by": null,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:FIND:INSUFFICIENT_PERMISSION"
}
Example response (404, Activation code not found):
{
"message": "Activation code not found",
"code": "ACTIVATION_CODE:FIND:CODE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
Create activation code
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/activation-codes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 6,
"code": "AG34WZ",
"created_by": null,
"used_by": null,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Server error):
{
"message": "Server error: activation code not created",
"code": "ACTIVATION_CODE:CREATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
Create activation code (multi-region)
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/activation-codes/7" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes/7"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 7,
"code": "JPAR6A",
"created_by": null,
"used_by": null,
"used_at": null,
"active": 0,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
Deactivate activation code
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/activation-codes/11" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/activation-codes/11"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202):
{
"id": 8,
"code": "JV7BTM",
"created_by": null,
"used_by": null,
"used_at": null,
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage activation codes",
"code": "ACTIVATION_CODE:DEACTIVATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Activation code is not active):
{
"message": "Cannot deactivate: code is not active",
"code": "ACTIVATION_CODE:DEACTIVATE:CODE_NOT_ACTIVE"
}
Example response (404, Activation code not found):
{
"message": "Activation code not found",
"code": "ACTIVATION_CODE:DEACTIVATE:CODE_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: activation code not deactivated",
"code": "ACTIVATION_CODE:DEACTIVATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Activation code ID.
code
string
Activation code value.
created_by
integer
ID of the user who created this code.
used_by
integer
ID of the user who used this code.
used_at
string
Timestamp when the code was used.
active
boolean
Whether the code is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
creator
object
User who created this code.
user
object
User who used this code.
Authentication
API endpoints for managing authentication
Login user
Example request:
curl --request POST \
"http://localhost:8000/api/login" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"test@example.com\",
\"password\": \"secretpassword\"
}"
const url = new URL(
"http://localhost:8000/api/login"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "test@example.com",
"password": "secretpassword"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"access_token": "7|x7de9EgE0xiBNLgHU91DHvhj85HVgTG1bekCssIA",
"expires": "2021-10-25 17:05:25"
}
Example response (403, Too many attempts):
{
"message": "Login: too many attempts",
"code": "GENERAL:TOO_MANY_ATTEMPTS"
}
Example response (422, Invalid credentials):
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Given credentials not found"
]
},
"code": "AUTH:LOGIN:INVALID_CREDENTIALS"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Register user
Example request:
curl --request POST \
"http://localhost:8000/api/register" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"region\": \"us\",
\"name\": \"Tom Smith\",
\"email\": \"name@domain.com\",
\"password\": \"Test123!\",
\"phone\": \"619-736-8088\",
\"phone_country\": \"US\",
\"language\": \"en\",
\"clinic_name\": \"Jaskolski, Bednar and Zulauf\",
\"clinic_location\": \"Ebertberg\",
\"address1\": \"647 Hilario Streets Suite 292\",
\"address2\": \"Walkershire, TX 15264\",
\"mfa_enabled\": true,
\"mfa_method\": \"email\",
\"activation_code\": \"1A2B3C\"
}"
const url = new URL(
"http://localhost:8000/api/register"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"region": "us",
"name": "Tom Smith",
"email": "name@domain.com",
"password": "Test123!",
"phone": "619-736-8088",
"phone_country": "US",
"language": "en",
"clinic_name": "Jaskolski, Bednar and Zulauf",
"clinic_location": "Ebertberg",
"address1": "647 Hilario Streets Suite 292",
"address2": "Walkershire, TX 15264",
"mfa_enabled": true,
"mfa_method": "email",
"activation_code": "1A2B3C"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 2,
"mrn": "2WZ3KKCX1790076257",
"name": "Dr. Hassie Koch I",
"email": "1790076257zgoldner@example.org",
"language": "en",
"phone": "(571) 609-0723",
"phone_country": "JP",
"phone_verified_at": null,
"address1": "344 Johnston Extension",
"address2": "South Laurianeton, CA 30114",
"postal_code": "75015",
"city": "Robel, Purdy and Reichert",
"country": "LU",
"clinic_name": "Lake Gardnerland",
"clinic_location": "89707 Haag Hill\nWest Reedville, HI 45911-4757",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:18.000000Z",
"updated_at": "2026-09-22T11:24:18.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 3,
"name": "ClinicAdmin"
}
]
}
Example response (403, Too many attempts):
{
"message": "Register: too many attempts",
"code": "GENERAL:TOO_MANY_ATTEMPTS"
}
Example response (403, E-mail in use (in another region)):
{
"message": "E-mail address already in use (in another region)",
"code": "AUTH:REGISTER:EMAIL_IN_USE"
}
Example response (403, Activation code is incorrect):
{
"message": "Activation code is incorrect",
"code": "AUTH:REGISTER:INCORRECT_CODE"
}
Example response (500, Server error):
{
"message": "Server error: user not created",
"code": "AUTH:REGISTER:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Register mobile user
Example request:
curl --request POST \
"http://localhost:8000/api/mobile/register" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"region\": \"us\",
\"name\": \"Tom Smith\",
\"email\": \"name@domain.com\",
\"password\": \"Test123!\",
\"language\": \"en\",
\"terms_accepted\": true
}"
const url = new URL(
"http://localhost:8000/api/mobile/register"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"region": "us",
"name": "Tom Smith",
"email": "name@domain.com",
"password": "Test123!",
"language": "en",
"terms_accepted": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"mrn": "AJYHJ26M1790076258",
"name": "Mr. Leonard Connelly I",
"email": "1790076258laverne07@example.org",
"language": "en",
"phone": "+1 (510) 941-5545",
"phone_country": "NO",
"phone_verified_at": null,
"address1": "617 Stevie Drive Suite 421",
"address2": "Tessiebury, AR 50882",
"postal_code": "97389-0308",
"city": "Rippin-Padberg",
"country": "SI",
"clinic_name": "Schadenchester",
"clinic_location": "940 Mertz Fort\nOkunevaton, NJ 27605-0896",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:18.000000Z",
"updated_at": "2026-09-22T11:24:18.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 3,
"name": "ClinicAdmin"
}
]
}
Example response (403, Too many attempts):
{
"message": "Register: too many attempts",
"code": "GENERAL:TOO_MANY_ATTEMPTS"
}
Example response (403, E-mail in use (in another region)):
{
"message": "E-mail address already in use (in another region)",
"code": "AUTH:MOBILE_REGISTER:EMAIL_IN_USE"
}
Example response (500, Server error):
{
"message": "Server error: user not created",
"code": "AUTH:MOBILE_REGISTER:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Request password reset
Request sending password reset email message with token that allows to change the password
Example request:
curl --request POST \
"http://localhost:8000/api/password/reset" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"test@example.com\"
}"
const url = new URL(
"http://localhost:8000/api/password/reset"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "test@example.com"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"code": "passwords.sent",
"message": "Reset password link successfully sent"
}
Example response (400, Throttled request):
{
"code": "passwords.throttled",
"message": "You have requested password reset recently"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Verify password reset token
Check if token is valid before using it to reset password
Example request:
curl --request POST \
"http://localhost:8000/api/password/reset/verify" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token\": \"158bed12188492617e43ecfcca43f5990b3f5f0383b5083247389482b70af019\",
\"email\": \"test@example.com\"
}"
const url = new URL(
"http://localhost:8000/api/password/reset/verify"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token": "158bed12188492617e43ecfcca43f5990b3f5f0383b5083247389482b70af019",
"email": "test@example.com"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"message": "Valid token",
"code": "AUTH:PASSWORD_RESET_VERIFY:VALID_TOKEN"
}
Example response (400, Invalid token):
{
"message": "Invalid token",
"code": "AUTH:PASSWORD_RESET_VERIFY:INVALID_TOKEN"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Change password with token
Change user password using password reset token sent to email address
Example request:
curl --request POST \
"http://localhost:8000/api/password/reset/change" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token\": \"158bed12188492617e43ecfcca43f5990b3f5f0383b5083247389482b70af019\",
\"email\": \"test@example.com\",
\"password\": \"secretpassword\"
}"
const url = new URL(
"http://localhost:8000/api/password/reset/change"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token": "158bed12188492617e43ecfcca43f5990b3f5f0383b5083247389482b70af019",
"email": "test@example.com",
"password": "secretpassword"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"code": "passwords.reset",
"message": "Password changed successfully"
}
Example response (400, Invalid token):
{
"code": "passwords.token",
"message": "Invalid token"
}
Example response (404, User not found):
{
"code": "passwords.user",
"message": "User not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logout current device
requires authentication
Logout and delete current access token
Example request:
curl --request POST \
"http://localhost:8000/api/logout" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/logout"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
[]
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logout everywhere
requires authentication
Logout and delete all access tokens owned by account
Example request:
curl --request POST \
"http://localhost:8000/api/logout/everywhere" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/logout/everywhere"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
[]
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Refresh access token
requires authentication
Refresh the new access token from the expiring token
Example request:
curl --request POST \
"http://localhost:8000/api/token/refresh" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/token/refresh"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"access_token": "7|x7de9EgE0xiBNLgHU91DHvhj85HVgTG1bekCssIA",
"expires": "2021-10-25 17:05:25"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check MFA status
requires authentication
Check any of available MFA methods. Supported methods: email, sms, otp.
Example request:
curl --request GET \
--get "http://localhost:8000/api/mfa/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mfa/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"enabled": 1,
"method": "email",
"phone": 1,
"otp": 1
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
enabled
string
Determines if user enabled MFA
method
string
Preferred MFA method
phone
string
Determines if user has verified phone number and sms channel could be used
otp
string
Determines if user has setup OTP with authenticator application
Use recovery code
requires authentication
Use generated recovery code in order to access account in case when other MFA methods couldn't be used. This method only checks if code is valid, implement account access scenario on your own. Sent code is removed and couldn't be used anymore. If remaining_codes counter equals zero, generate a new set.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/recovery-code" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"code\": \"ZZASRM6S\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/recovery-code"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"code": "ZZASRM6S"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"access_token": "7|x7de9EgE0xiBNLgHU91DHvhj85HVgTG1bekCssIA",
"expires": "2021-10-25 17:05:25",
"remaining_codes": 9
}
Example response (401, Invalid code):
{
"message": "Invalid code",
"code": "AUTH:USE_RECOVERY_CODE:INVALID_CODE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send MFA code
requires authentication
Send multi-factor authentication code via selected channel. Code is valid for 15 minutes.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/send" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"channel\": \"email\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/send"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"channel": "email"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"message": "Code sent",
"code": "AUTH:SEND_MFA:SENT"
}
Example response (400, Channel SMS, phone number not verified):
{
"message": "Phone number is not verified",
"code": "AUTH:SEND_MFA:PHONE_NUMBER_NOT_VERIFIED"
}
Example response (500, Channel SMS, provider problem):
{
"message": "Code sending failed",
"code": "AUTH:SEND_MFA:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Verify MFA code
requires authentication
Verify multi-factor code obtained from selected channel.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/verify" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"channel\": \"email\",
\"remember_mfa_session\": true,
\"code\": \"445566\",
\"machine_key\": \"35282880-244a-4328-9435-2aaf432f3619\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/verify"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"channel": "email",
"remember_mfa_session": true,
"code": "445566",
"machine_key": "35282880-244a-4328-9435-2aaf432f3619"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK, token auth):
{
"access_token": "7|x7de9EgE0xiBNLgHU91DHvhj85HVgTG1bekCssIA",
"expires": "2021-10-25 17:05:25",
"mfa_token": "fd63e55c-2a67-44b2-95b9-a771778e9971",
"mfa_expires": "2023-04-25 21:00:00"
}
Example response (200, OK, cookie auth):
{
"message": "OK",
"mfa_token": "fd63e55c-2a67-44b2-95b9-a771778e9971",
"mfa_expires": "2023-04-25 21:00:00"
}
Example response (401, Invalid code):
{
"message": "Invalid code",
"code": "AUTH:VERIFY_MFA:INVALID_CODE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Verify phone number
requires authentication
Verify phone number with text message
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/phone/verify" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"code\": \"445566\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/phone/verify"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"code": "445566"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"message": "Phone number verified",
"code": "AUTH:VERIFY_PHONE:VERIFIED"
}
Example response (401, Invalid code):
{
"message": "Invalid code",
"code": "AUTH:VERIFY_PHONE:INVALID_CODE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Verify MFA OTP
requires authentication
Verify one-time password (OTP). If verification is successful, new access token with additional permissions will be generated.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/otp/verify" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"code\": \"445566\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/otp/verify"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"code": "445566"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK, token auth):
{
"access_token": "7|x7de9EgE0xiBNLgHU91DHvhj85HVgTG1bekCssIA",
"expires": "2021-10-25 17:05:25"
}
Example response (200, OK, cookie auth):
{
"message": "OK"
}
Example response (401, Invalid code):
{
"message": "Invalid code",
"code": "AUTH:VERIFY_MFA_OTP:INVALID_CODE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Change password
requires authentication
Change authenticated user password
Example request:
curl --request POST \
"http://localhost:8000/api/password/change" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"old_password\": \"oldpassword\",
\"new_password\": \"newpassword\"
}"
const url = new URL(
"http://localhost:8000/api/password/change"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"old_password": "oldpassword",
"new_password": "newpassword"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"message": "Password changed successfully",
"code": "AUTH:PASSWORD_CHANGE:CHANGED"
}
Example response (422, Invalid old password):
{
"message": "The given data was invalid.",
"errors": {
"old_password": [
"Old password is incorrect"
]
},
"code": "AUTH:PASSWORD_CHANGE:INVALID_OLD_PASSWORD"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set MFA status
requires authentication
Set MFA status and preferred method. Supported methods: email, sms, otp.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"enabled\": true,
\"method\": \"email\"
}"
const url = new URL(
"http://localhost:8000/api/mfa/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"enabled": true,
"method": "email"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"enabled": 1,
"method": "email",
"phone": 1,
"otp": 1
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Generate recovery codes
requires authentication
Generate recovery codes for authenticated user and revoke old ones. User could use these codes in case when couldn't use any of MFA methods (e.g. lost device with OTP app or device is not accessible right now).
Example request:
curl --request GET \
--get "http://localhost:8000/api/mfa/recovery-codes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mfa/recovery-codes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"recovery_codes": [
"A3H8PF8P",
"IZ8CGK2H",
"DTYENLLT",
"0RKEZFST",
"9MPW91BS",
"S38Z6HS6",
"UF5ATOKP",
"HSZXP8EL",
"ZZASRM6S",
"07GR4CD1"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Setup MFA OTP
requires authentication
Setup multi-factor authentication with one-time passwords (OTP). Use secret on your own or generate QR code with given url. Then user could scan QR code with authentication app (e.g. Microsoft Authenticator, Authy). If secret has been already generated, new secret will override existing one and revoke previous setup.
Example request:
curl --request POST \
"http://localhost:8000/api/mfa/otp/setup" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mfa/otp/setup"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"secret": "VXGJ6JMIAWWDFXYDLKO3VG3RSGTS34BGMVTGQIEHMVVMJ2JBGCSNPQZDV4B6OMDIGI4UKCVCVKVMA7EASLHZEJWW4ZNKLAUTSZYN7EA",
"url": "otpauth://totp/AetherDigitalTherapy?issuer=AetherDigitalTherapy&secret=VXGJ6JMIAWWDFXYDLKO3VG3RSGTS34BGMVTGQIEHMVVMJ2JBGCSNPQZDV4B6OMDIGI4UKCVCVKVMA7EASLHZEJWW4ZNKLAUTSZYN7EA",
"recovery_codes": [
"A3H8PF8P",
"IZ8CGK2H",
"DTYENLLT",
"0RKEZFST",
"9MPW91BS",
"S38Z6HS6",
"UF5ATOKP",
"HSZXP8EL",
"ZZASRM6S",
"07GR4CD1"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Login user (SPA)
Authorize user and create cookie-based session. Hit GET /sanctum/csrf-cookie endpoint to retrieve XSRF-TOKEN cookie. Then attach X-XSRF-TOKEN HTTP header to any request to authorize. See more: Laravel Sanctum documentation
Example request:
curl --request POST \
"http://localhost:8000/login" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"test@example.com\",
\"password\": \"secretpassword\"
}"
const url = new URL(
"http://localhost:8000/login"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "test@example.com",
"password": "secretpassword"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 332,
"mrn": "PPCYLPH41790076430",
"name": "Miss Micaela Dicki",
"email": "1790076430mya05@example.com",
"language": "en",
"phone": "+1-520-359-9748",
"phone_country": "SY",
"phone_verified_at": null,
"address1": "6727 O'Hara Rue",
"address2": "Isaiborough, HI 91768-4936",
"postal_code": "79603",
"city": "Haley, Erdman and Lowe",
"country": "FR",
"clinic_name": "Reillymouth",
"clinic_location": "330 Luis Ferry\nCorrinemouth, WY 87875",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:27:10.000000Z",
"updated_at": "2026-09-22T11:27:10.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
Example response (403, Too many attempts):
{
"message": "Login: too many attempts",
"code": "GENERAL:TOO_MANY_ATTEMPTS"
}
Example response (422, Invalid credentials):
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Given credentials not found"
]
},
"code": "AUTH:LOGIN_COOKIE:INVALID_CREDENTIALS"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Chat
API endpoints for chat management
Authorize a user
requires authentication
This method authorizes a user using Ably service. Endpoint used only by Ably SDK
Check more details on https://ably.com/docs/auth/token
List all chat rooms
requires authentication
This method retrieves all chat rooms. Possible extend options:
- participants - user assigned to chat room
- participants.roles - roles assigned to chat participants
- owner - the clinician assigned to patient
- patient - the patient for whom the chat was created
- messages - the messages related to chat room
- messages.author - the author of message/li>
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/rooms" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/rooms"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"owner": null,
"patient_id": null,
"encryption_key": "w7ZO52StXImv54u9ihxVPZGt9V/PFEwstuhuTDS9UII=",
"name": "omnis",
"friendly_name": "omnis",
"created_at": "2026-09-22T11:26:47.000000Z",
"deleted_at": null,
"updated_at": "2026-09-22T11:26:47.000000Z"
},
{
"id": 2,
"owner": null,
"patient_id": null,
"encryption_key": "VUFzE8wVUyAgPFADgbDwSPVPS8aTZTL//6lqeM1UlzM=",
"name": "eaque",
"friendly_name": "eaque",
"created_at": "2026-09-22T11:26:47.000000Z",
"deleted_at": null,
"updated_at": "2026-09-22T11:26:47.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list chat room",
"code": "CHAT:LIST_ROOMS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Chat room ID.
name
string
Chat room name (channel SID).
friendly_name
string
Human-readable chat room name.
owner
integer
User ID of the room owner.
patient_id
integer
Associated patient user ID.
encryption_key
string
Encryption key for the chat room.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
messages
object[]
Chat room messages.
last_message
object
Last message in the chat room.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Retrieve a chat room
requires authentication
This method retrieves a single chat room identified by roomId. Possible extend options:
- participants - user assigned to chat room
- owner - the clinician assigned to patient
- patient - the patient for whom the chat was created
- messages - the messages related to chat room
- messages.author - the author of message/li>
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/room/ipsa" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/room/ipsa"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 3,
"owner": null,
"patient_id": null,
"encryption_key": "MPQYPDLEmv6OpYs9RgC1NsSDKkG8Xhe3QwnDVo2RtI0=",
"name": "aliquam",
"friendly_name": "aliquam",
"created_at": "2026-09-22T11:26:47.000000Z",
"deleted_at": null,
"updated_at": "2026-09-22T11:26:47.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view chat room",
"code": "CHAT:GET_ROOM:INSUFFICIENT_PERMISSION"
}
Example response (404, Chat room not found):
{
"message": "Chat room not found",
"code": "CHAT:GET_ROOM:ROOM_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Chat room ID.
name
string
Chat room name (channel SID).
friendly_name
string
Human-readable chat room name.
owner
integer
User ID of the room owner.
patient_id
integer
Associated patient user ID.
encryption_key
string
Encryption key for the chat room.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
messages
object[]
Chat room messages.
last_message
object
Last message in the chat room.
Create a new chat room
requires authentication
This method creates a new chat room using the authenticated user's ID, a name for the room, and a list of participants.
The list of participants should contain the IDs of the users who will be participants in the room.
Example request:
curl --request POST \
"http://localhost:8000/api/chat/room" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"owner\": 1,
\"name\": \"my-chat\",
\"patient_id\": 1,
\"participants\": [
\"1\"
]
}"
const url = new URL(
"http://localhost:8000/api/chat/room"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"owner": 1,
"name": "my-chat",
"patient_id": 1,
"participants": [
"1"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"owner": null,
"patient_id": null,
"encryption_key": "mHLnLEXaAdWCayyelqnsrwiSwpBPTU30aUsomj9wAM4=",
"name": "quos",
"friendly_name": "quos",
"created_at": "2026-09-22T11:26:47.000000Z",
"deleted_at": null,
"updated_at": "2026-09-22T11:26:47.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view chat room",
"code": "CHAT:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Chat room ID.
name
string
Chat room name (channel SID).
friendly_name
string
Human-readable chat room name.
owner
integer
User ID of the room owner.
patient_id
integer
Associated patient user ID.
encryption_key
string
Encryption key for the chat room.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
messages
object[]
Chat room messages.
last_message
object
Last message in the chat room.
Update an existing chat room
requires authentication
This method updates an existing chat room using the authenticated user's ID, a new name for the room, and a list of participants.
The list of participants should contain the IDs of the users who will be participants in the room.
Example request:
curl --request PUT \
"http://localhost:8000/api/chat/room/ut" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"owner\": 1,
\"name\": \"my-chat\",
\"participants\": [
\"1\"
],
\"participants_del\": [
\"1\"
]
}"
const url = new URL(
"http://localhost:8000/api/chat/room/ut"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"owner": 1,
"name": "my-chat",
"participants": [
"1"
],
"participants_del": [
"1"
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 5,
"owner": null,
"patient_id": null,
"encryption_key": "uFE6o1+NsBvzT0A73dBamoF8hnlXlNSB109iAB/LmEc=",
"name": "ratione",
"friendly_name": "ratione",
"created_at": "2026-09-22T11:26:47.000000Z",
"deleted_at": null,
"updated_at": "2026-09-22T11:26:47.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update chat room",
"code": "CHAT:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Chat room not found):
{
"message": "Chat room not found",
"code": "CHAT:UPDATE:ROOM_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Chat room ID.
name
string
Chat room name (channel SID).
friendly_name
string
Human-readable chat room name.
owner
integer
User ID of the room owner.
patient_id
integer
Associated patient user ID.
encryption_key
string
Encryption key for the chat room.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
messages
object[]
Chat room messages.
last_message
object
Last message in the chat room.
Chat room archives
requires authentication
Get archived messages for room Possible extend options:
- author - this field represent user who send message
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/room/culpa/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/room/culpa/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 5,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": "651a8e4868d5dc27c0000cc2",
"channel": "chat.messages.room.44.56bf7d37-4ed6-4db4-947b-d68a1066677c.communication-channel",
"clientId": "95",
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"data": "{\"encryptedMessage\":{\"message\":\"z6z1zNihCjlEePltz+BG8g==\",\"initialVector\":\"7376fcbf0b32fbdcd5c5b62c087b7600\"},\"user\":{\"id\":95,\"name\":\"Bartosz Druga firmaa\",\"email\":\"bartosz+drugafirma@refericon.pl\",\"image\":\"https://aether-dev-bucket.s3.amazonaws.com/users/7T6im01PAj4cahksWHllrL7se2SQ9buquIjGGFtp.jpg\",\"permissions\":[],\"roles\":[{\"id\":2,\"name\":\"Clinician\"}]},\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"recipients\":[{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"95\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"44\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"1250\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"3067\"}]}",
"name": "message",
"recipients": [
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": true,
"clientId": "95"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "44"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "1250"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "3067"
}
],
"timestamp": 1696239176715,
"created_at": "2023-10-02 09:32:56"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view archived messages",
"code": "CHAT:GET_ARCHIVES:INSUFFICIENT_PERMISSION"
}
Example response (404, Chat room not found):
{
"message": "Chat room not found",
"code": "CHAT:GET_ARCHIVES:ROOM_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Unread messages
requires authentication
Get unread messaged for chat room. Possible extend options:
- author - this field represent user who send message
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/messages/unread?room=18" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/messages/unread"
);
const params = {
"room": "18",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 5,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": "651a8e4868d5dc27c0000cc2",
"channel": "chat.messages.room.44.56bf7d37-4ed6-4db4-947b-d68a1066677c.communication-channel",
"clientId": "95",
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"data": "{\"encryptedMessage\":{\"message\":\"z6z1zNihCjlEePltz+BG8g==\",\"initialVector\":\"7376fcbf0b32fbdcd5c5b62c087b7600\"},\"user\":{\"id\":95,\"name\":\"Bartosz Druga firmaa\",\"email\":\"bartosz+drugafirma@refericon.pl\",\"image\":\"https://aether-dev-bucket.s3.amazonaws.com/users/7T6im01PAj4cahksWHllrL7se2SQ9buquIjGGFtp.jpg\",\"permissions\":[],\"roles\":[{\"id\":2,\"name\":\"Clinician\"}]},\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"recipients\":[{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"95\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"44\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"1250\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"3067\"}]}",
"name": "message",
"recipients": [
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": true,
"clientId": "95"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "44"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "1250"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "3067"
}
],
"timestamp": 1696239176715,
"created_at": "2023-10-02 09:32:56"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view unread messages list",
"code": "CHAT:UNREAD_MESSAGES:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete chat message
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/chat/messages/18?msgId=quia" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/messages/18"
);
const params = {
"msgId": "quia",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 5,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": "651a8e4868d5dc27c0000cc2",
"channel": "chat.messages.room.44.56bf7d37-4ed6-4db4-947b-d68a1066677c.communication-channel",
"clientId": "95",
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"data": "{\"encryptedMessage\":{\"message\":\"z6z1zNihCjlEePltz+BG8g==\",\"initialVector\":\"7376fcbf0b32fbdcd5c5b62c087b7600\"},\"user\":{\"id\":95,\"name\":\"Bartosz Druga firmaa\",\"email\":\"bartosz+drugafirma@refericon.pl\",\"image\":\"https://aether-dev-bucket.s3.amazonaws.com/users/7T6im01PAj4cahksWHllrL7se2SQ9buquIjGGFtp.jpg\",\"permissions\":[],\"roles\":[{\"id\":2,\"name\":\"Clinician\"}]},\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"recipients\":[{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"95\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"44\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"1250\"},{\"delivered\":true,\"msgId\":\"b8673175-01e6-4b6d-9032-226d3df20637\",\"seen\":false,\"clientId\":\"3067\"}]}",
"name": "message",
"recipients": [
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": true,
"clientId": "95"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "44"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "1250"
},
{
"delivered": true,
"msgId": "b8673175-01e6-4b6d-9032-226d3df20637",
"seen": false,
"clientId": "3067"
}
],
"timestamp": 1696239176715,
"created_at": "2023-10-02 09:32:56"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete message",
"code": "CHAT:DELETE_MESSAGE:INSUFFICIENT_PERMISSION"
}
Example response (404, Message not found):
{
"message": "Chat message not found",
"code": "CHAT:DELETE_MESSAGE:MESSAGE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get tickets list for chat room
requires authentication
Possible extend options:
- sender - the user who created ticket
- recipient - the user who was ticket recipient
- messages - message allocated to ticket
- messages.attachments - list of attachments assigned to message and ticket
- messages.sender - the user who wrote the message
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/tickets/consequuntur?status=nisi&sender=10&recipient=11" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/tickets/consequuntur"
);
const params = {
"status": "nisi",
"sender": "10",
"recipient": "11",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 87,
"sender_id": 293,
"recipient_id": 294,
"device_id": null,
"meeting_date": "2026-09-22 11:26:47",
"meeting_type": "online_meeting",
"contact_email": "saul38@yahoo.com",
"status": "new",
"created_at": "2026-09-22T11:26:48.000000Z",
"updated_at": "2026-09-22T11:26:48.000000Z",
"sender": {
"id": 293,
"mrn": "QQB9K7ED1790076407",
"name": "Lea Adams",
"email": "1790076407skiles.ola@example.com",
"language": "en",
"phone": "(530) 605-9430",
"phone_country": "CM",
"phone_verified_at": null,
"address1": "650 Wilmer Shoal",
"address2": "Lake Edfort, VT 67071-0531",
"postal_code": "09823-4997",
"city": "Mitchell-Kessler",
"country": "SE",
"clinic_name": "Port Lonny",
"clinic_location": "72472 Gleichner Center Apt. 886\nLake Dellaview, SD 67770",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:47.000000Z",
"updated_at": "2026-09-22T11:26:47.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 294,
"mrn": "VA42NKG51790076407",
"name": "Bert Johns",
"email": "1790076407wbaumbach@example.com",
"language": "en",
"phone": "762-654-4608",
"phone_country": "AR",
"phone_verified_at": null,
"address1": "1141 Lauryn Landing Suite 292",
"address2": "West Wiltonville, NV 84358-4978",
"postal_code": "68717-5651",
"city": "Ullrich-Collier",
"country": "BG",
"clinic_name": "West Elisa",
"clinic_location": "90147 Nolan Road Suite 967\nSouth Annaliseton, NH 73643",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:47.000000Z",
"updated_at": "2026-09-22T11:26:47.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": null,
"messages": []
},
{
"id": 88,
"sender_id": 295,
"recipient_id": 296,
"device_id": null,
"meeting_date": "2026-09-22 11:26:48",
"meeting_type": "online_meeting",
"contact_email": "rempel.shany@medhurst.com",
"status": "new",
"created_at": "2026-09-22T11:26:49.000000Z",
"updated_at": "2026-09-22T11:26:49.000000Z",
"sender": {
"id": 295,
"mrn": "DPGY999N1790076408",
"name": "Helene Ledner DVM",
"email": "1790076408murphy.karlie@example.org",
"language": "en",
"phone": "+1.248.708.4411",
"phone_country": "EH",
"phone_verified_at": null,
"address1": "221 Celia Corners",
"address2": "Terencefort, MN 09880",
"postal_code": "84762-8900",
"city": "Flatley and Sons",
"country": "GB",
"clinic_name": "Jakubowskiview",
"clinic_location": "67584 Schmeler Isle Suite 152\nMonroeview, WA 79263",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:48.000000Z",
"updated_at": "2026-09-22T11:26:48.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 296,
"mrn": "YHBMTNHU1790076408",
"name": "Prof. Ignatius Corwin PhD",
"email": "1790076408presley.auer@example.com",
"language": "en",
"phone": "+1-320-267-2804",
"phone_country": "FK",
"phone_verified_at": null,
"address1": "5494 Marina Land Apt. 828",
"address2": "Paulamouth, NM 89004",
"postal_code": "88628",
"city": "Bogan-Zieme",
"country": "GR",
"clinic_name": "Port Cullenbury",
"clinic_location": "2402 Makenzie Parks Suite 328\nWest Jadonville, MO 90342",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:48.000000Z",
"updated_at": "2026-09-22T11:26:48.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": null,
"messages": []
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view chat room tickets",
"code": "CHAT:LIST_TICKETS:INSUFFICIENT_PERMISSION"
}
Example response (404, Chat room not found):
{
"message": "Chat room not found",
"code": "CHAT:LIST_TICKETS:ROOM_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
List of available patients for chat
requires authentication
Possible extend options:
- clinician - clinician assigned to this user
- devices - products assigned to user
- roles - user roles
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/available-patients" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/available-patients"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 297,
"mrn": "MRKMVJE41790076409",
"name": "Laurie Legros",
"email": "1790076409auer.yasmin@example.org",
"language": "en",
"phone": "(520) 303-4881",
"phone_country": "SS",
"phone_verified_at": null,
"address1": "288 Rosemarie Spring Apt. 203",
"address2": "Lake Kristofferland, UT 87821-9668",
"postal_code": "48738-6079",
"city": "Russel, Hintz and Dietrich",
"country": "PT",
"clinic_name": "Majorside",
"clinic_location": "200 Stark Flat\nPort Lina, GA 36186-2949",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:49.000000Z",
"updated_at": "2026-09-22T11:26:49.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"devices": [
{
"id": 154,
"serial": "0fc10418-883c-386a-bbf8-5b245332d3de",
"bluetooth_id": "d6f84513-4b35-34a7-b9f0-219d276c0049",
"company_id": null,
"model_id": null,
"amputee_id": 297,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:49.000000Z",
"updated_at": "2026-09-22T11:26:49.000000Z",
"first_config_change_at": null
}
],
"roles": [
{
"id": 1,
"name": "SuperAdmin"
}
]
},
{
"id": 298,
"mrn": "7LC3B3QA1790076409",
"name": "Rebekah Nicolas",
"email": "1790076409uruecker@example.net",
"language": "en",
"phone": "(475) 997-8345",
"phone_country": "JE",
"phone_verified_at": null,
"address1": "80198 Josie Wall",
"address2": "Johnniefurt, IN 75314",
"postal_code": "27749",
"city": "Beahan Inc",
"country": "LT",
"clinic_name": "Lake Okeyland",
"clinic_location": "97355 Jocelyn Key Apt. 607\nBauchstad, MO 49720-9489",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:49.000000Z",
"updated_at": "2026-09-22T11:26:49.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"devices": [
{
"id": 155,
"serial": "2ed0ace6-9540-37c3-bbb0-1a5d3012b30a",
"bluetooth_id": "3479ff2b-33cb-31bf-b9c8-9647f367a032",
"company_id": null,
"model_id": null,
"amputee_id": 298,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:50.000000Z",
"updated_at": "2026-09-22T11:26:50.000000Z",
"first_config_change_at": null
}
],
"roles": [
{
"id": 5,
"name": "ClinicianSupport"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list available patients",
"code": "CHAT:LIST_PATIENTS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
List of available participants for chat
requires authentication
Possible extend options:
- roles - user roles
- permissions - user permissions
Example request:
curl --request GET \
--get "http://localhost:8000/api/chat/room/1/available-participants" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/chat/room/1/available-participants"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 299,
"mrn": "XUSNNJBW1790076410",
"name": "Merle Rice",
"email": "1790076410jason79@example.net",
"language": "en",
"phone": "+1-207-414-3516",
"phone_country": "DM",
"phone_verified_at": null,
"address1": "354 Adalberto Drives Suite 966",
"address2": "Stammburgh, CO 18111-0992",
"postal_code": "36005-8356",
"city": "Swaniawski, Luettgen and Sipes",
"country": "NO",
"clinic_name": "North Chelsieburgh",
"clinic_location": "898 Pfannerstill Island\nMariahside, GA 56262-9683",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:50.000000Z",
"updated_at": "2026-09-22T11:26:50.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 5,
"name": "ClinicianSupport"
}
]
},
{
"id": 300,
"mrn": "ER4XE5AS1790076410",
"name": "Tre Hettinger",
"email": "1790076410rosamond80@example.org",
"language": "en",
"phone": "469.408.6882",
"phone_country": "HU",
"phone_verified_at": null,
"address1": "12397 Carole Hill",
"address2": "North Alvisville, MN 89280",
"postal_code": "50761",
"city": "Emmerich LLC",
"country": "MT",
"clinic_name": "Lake Johan",
"clinic_location": "64055 Alda Island\nNorth Kayleigh, MO 11323-0010",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:51.000000Z",
"updated_at": "2026-09-22T11:26:51.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 3,
"name": "ClinicAdmin"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list available participants",
"code": "CHAT:LIST_PARTICIPANTS:INSUFFICIENT_PERMISSION"
}
Example response (404, Chat room not found):
{
"message": "Chat room not found",
"code": "CHAT:LIST_PARTICIPANTS:ROOM_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Community
Endpoints related to community videos
List community videos
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/videos?include_unpublished=" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos"
);
const params = {
"include_unpublished": "0",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.1",
"translation_status": "SUCCESS",
"processing_status": "ready",
"published_at": "2026-07-31T12:59:20.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "published"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view community videos",
"code": "COMMUNITY_VIDEOS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get community video
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/videos/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.1",
"translation_status": "SUCCESS",
"processing_status": "ready",
"published_at": "2026-07-31T12:59:20.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "published"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view community videos",
"code": "COMMUNITY_VIDEOS:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:GET:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Upload community video
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "author_id=1"\
--form "description=A short clip about adapting to a new prosthesis."\
--form "video=@/tmp/php7Eno8Z" const url = new URL(
"http://localhost:8000/api/community/videos"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('author_id', '1');
body.append('description', 'A short clip about adapting to a new prosthesis.');
body.append('video', document.querySelector('input[name="video"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_VIDEOS:UPLOAD:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update community video
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/community/videos/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"author_id\": 1,
\"description\": \"A short clip about adapting to a new prosthesis.\"
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"author_id": 1,
"description": "A short clip about adapting to a new prosthesis."
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.us.1",
"translation_status": "STARTED",
"processing_status": "ready",
"published_at": "2026-07-31T12:59:20.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "published"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_VIDEOS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:UPDATE:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Publish community video
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/publish" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"published_at\": \"2026-08-25 12:00:00\"
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1/publish"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"published_at": "2026-08-25 12:00:00"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.us.1",
"translation_status": "SUCCESS",
"processing_status": "ready",
"published_at": "2026-07-31T12:59:20.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "published"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_VIDEOS:PUBLISH:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:PUBLISH:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Unpublish community video
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/unpublish" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1/unpublish"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.us.1",
"translation_status": "SUCCESS",
"processing_status": "ready",
"published_at": "9999-12-31T23:59:59.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "unpublished"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_VIDEOS:UNPUBLISH:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:UNPUBLISH:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
React to community video
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/react" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1/react"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, Current reaction state):
{
"status": true
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to react to community videos",
"code": "COMMUNITY_VIDEOS:REACT:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:REACT:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update community video categories
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/community/videos/1/categories" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"categories\": [
1,
2
]
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1/categories"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"categories": [
1,
2
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"author_id": 2,
"author_name": "Tom S.",
"author_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png",
"video_url": "/videos/1215397088",
"player_embed_url": "https://player.vimeo.com/video/1215397088?h=3bb25b045c",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us",
"description": "community_videos.production.1",
"translation_status": "SUCCESS",
"processing_status": "ready",
"published_at": "2026-07-31T12:59:20.000000Z",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"status": "published",
"categories": [
{
"id": 1,
"name": "community_categories.production.1",
"is_archived": false,
"translation_status": "SUCCESS",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d?region=us"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_VIDEOS:UPDATE_CATEGORIES:INSUFFICIENT_PERMISSION"
}
Example response (404, Video not found):
{
"message": "Community video not found",
"code": "COMMUNITY_VIDEOS:UPDATE_CATEGORIES:VIDEO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List community categories
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/categories" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/categories"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "community_categories.production.us.1",
"is_archived": false,
"translation_status": "SUCCESS",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d_540x960?region=us"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view community videos",
"code": "COMMUNITY_CATEGORIES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create community category
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/categories" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Sports\"
}"
const url = new URL(
"http://localhost:8000/api/community/categories"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Sports"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"name": "community_categories.production.us.1",
"is_archived": false,
"translation_status": "STARTED",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z",
"thumbnail_url": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_CATEGORIES:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update community category
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/community/categories/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Sports\"
}"
const url = new URL(
"http://localhost:8000/api/community/categories/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Sports"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 1,
"name": "community_categories.production.us.1",
"is_archived": false,
"translation_status": "STARTED",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-08-14T09:00:00.000000Z",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d_540x960?region=us"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_CATEGORIES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Category not found):
{
"message": "Community category not found",
"code": "COMMUNITY_CATEGORIES:UPDATE:CATEGORY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Archive community category
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/categories/1/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/categories/1/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"name": "community_categories.production.us.1",
"is_archived": true,
"translation_status": "SUCCESS",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-08-14T09:00:00.000000Z",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d_540x960?region=us"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_CATEGORIES:ARCHIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Category not found):
{
"message": "Community category not found",
"code": "COMMUNITY_CATEGORIES:ARCHIVE:CATEGORY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Unarchive community category
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/categories/1/unarchive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/categories/1/unarchive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"name": "community_categories.production.us.1",
"is_archived": false,
"translation_status": "SUCCESS",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-08-14T09:00:00.000000Z",
"thumbnail_url": "https://i.vimeocdn.com/video/2186556744-c0e3e0986946410a9a851a8b8acbc3be6c2b0e3b68ee0db18db107d0a1dd3204-d_540x960?region=us"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_CATEGORIES:UNARCHIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Category not found):
{
"message": "Community category not found",
"code": "COMMUNITY_CATEGORIES:UNARCHIVE:CATEGORY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List community category suggestions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/categories/suggestions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/categories/suggestions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"search_term": "Swimming",
"created_at": "2026-08-14T09:00:00.000000Z",
"updated_at": "2026-08-14T09:00:00.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_CATEGORY_SUGGESTIONS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create community category suggestion
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/categories/suggestions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"search_term\": \"Swimming\"
}"
const url = new URL(
"http://localhost:8000/api/community/categories/suggestions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"search_term": "Swimming"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"origin_region": "us",
"request_id": "us-4428bf54-08a7-43ec-b312-54874c2ef5d8",
"user_id": 1,
"search_term": "Swimming",
"created_at": "2026-08-14T09:00:00.000000Z",
"updated_at": "2026-08-14T09:00:00.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to suggest community categories",
"code": "COMMUNITY_CATEGORY_SUGGESTIONS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List community comments
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/videos/1/comments" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1/comments"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"video_id": 1,
"parent_comment_id": null,
"display_name": "John D.",
"is_ambassador": false,
"content": "Great video, thank you!",
"status": "approved",
"rejection_reason": null,
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z"
}
],
"items_pending": [],
"items_rejected": []
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to comment on community videos",
"code": "COMMUNITY_COMMENTS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create community comment
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/comments" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"content\": \"Great video, thank you!\"
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1/comments"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"content": "Great video, thank you!"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"video_id": 1,
"parent_comment_id": null,
"display_name": "John D.",
"is_ambassador": false,
"content": "Great video, thank you!",
"status": "pending",
"rejection_reason": null,
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to comment on community videos",
"code": "COMMUNITY_COMMENTS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update community comment
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/community/videos/1/comments/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"content\": \"Great video, thank you!\"
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1/comments/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"content": "Great video, thank you!"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 2,
"video_id": 1,
"parent_comment_id": 1,
"display_name": "John D.",
"is_ambassador": false,
"content": "Great video, thank you! (edited)",
"status": "pending",
"rejection_reason": null,
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to comment on community videos",
"code": "COMMUNITY_COMMENTS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Comment not found):
{
"message": "Community comment not found",
"code": "COMMUNITY_COMMENTS:UPDATE:COMMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete community comment
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/community/videos/1/comments/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1/comments/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (200):
{
"message": "Community comment deleted"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to comment on community videos",
"code": "COMMUNITY_COMMENTS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Comment not found):
{
"message": "Community comment not found",
"code": "COMMUNITY_COMMENTS:DELETE:COMMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Approve community comment
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/comments/1/approve" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/videos/1/comments/1/approve"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"video_id": 1,
"parent_comment_id": null,
"display_name": "John D.",
"is_ambassador": false,
"content": "Great video, thank you!",
"status": "approved",
"rejection_reason": null,
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_COMMENTS:APPROVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Comment not found):
{
"message": "Community comment not found",
"code": "COMMUNITY_COMMENTS:APPROVE:COMMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Reject community comment
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/videos/1/comments/1/reject" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"reason\": \"Contains inappropriate language.\"
}"
const url = new URL(
"http://localhost:8000/api/community/videos/1/comments/1/reject"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"reason": "Contains inappropriate language."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 1,
"video_id": 1,
"parent_comment_id": null,
"display_name": "John D.",
"is_ambassador": false,
"content": "Great video, thank you!",
"status": "rejected",
"rejection_reason": "Contains inappropriate language.",
"created_at": "2026-07-31T12:59:20.000000Z",
"updated_at": "2026-07-31T12:59:20.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_COMMENTS:REJECT:INSUFFICIENT_PERMISSION"
}
Example response (404, Comment not found):
{
"message": "Community comment not found",
"code": "COMMUNITY_COMMENTS:REJECT:COMMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get community statistics
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/statistics?date_from=2026-08-10&date_to=2026-08-14" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/statistics"
);
const params = {
"date_from": "2026-08-10",
"date_to": "2026-08-14",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"date_from": "2026-08-10",
"date_to": "2026-08-14",
"engaged_users_count": 42,
"content_resonance_percent": 63.5,
"push_uploads_percent": 27.3
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_STATISTICS:GET:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Record community tab open
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/statistics/tab-open" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/statistics/tab-open"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"message": "Community statistic recorded",
"code": "COMMUNITY_STATISTICS:RECORD:SUCCESS"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view community videos",
"code": "COMMUNITY_STATISTICS:TAB_OPEN:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List community ambassadors
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/community/ambassadors" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/community/ambassadors"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 1,
"count": 1,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"origin_region": "us",
"user_id": 1,
"name": "Tom S.",
"public_image": "https://example-bucket.s3.us-east-2.amazonaws.com/ambassadors/example.png"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_AMBASSADORS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Upload ambassador public image
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/community/ambassadors/1/public-image" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "public_image=@/tmp/phpc9y4Au" const url = new URL(
"http://localhost:8000/api/community/ambassadors/1/public-image"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('public_image', document.querySelector('input[name="public_image"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (200):
{
"id": 331,
"name": "Mollie Schumm",
"public_image": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage community videos",
"code": "COMMUNITY_AMBASSADORS:UPLOAD_PUBLIC_IMAGE:INSUFFICIENT_PERMISSION"
}
Example response (403, User is not an ambassador):
{
"message": "This user is not a community ambassador",
"code": "COMMUNITY_AMBASSADORS:UPLOAD_PUBLIC_IMAGE:NOT_AN_AMBASSADOR"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "COMMUNITY_AMBASSADORS:UPLOAD_PUBLIC_IMAGE:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Config
API endpoints for device config management
Get device config
requires authentication
Definitions:
- config - current config entries
- config history entry - set of changes in config, updated during the session
- config history change - single change made to config (part of config history entry)
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config?_format=porro" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config"
);
const params = {
"_format": "porro",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, Normal/compact response):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (200):
[
{
"id": 1,
"device_id": 22,
"mode_id": 1,
"key": "rerum",
"value": "incidunt",
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z",
"mode": {
"id": 1,
"device_id": 23,
"slot": null,
"name": "Sed qui autem recusandae maiores ex dolore.",
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
},
{
"id": 2,
"device_id": 24,
"mode_id": 2,
"key": "consequatur",
"value": "est",
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z",
"mode": {
"id": 2,
"device_id": 25,
"slot": null,
"name": "Aspernatur tenetur eligendi doloremque sed.",
"active": 1,
"created_at": "2026-09-22T11:24:42.000000Z",
"updated_at": "2026-09-22T11:24:42.000000Z"
}
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device config",
"code": "CONFIG:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:GET:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config entry ID.
device_id
integer
Associated device ID.
mode_id
integer
Associated config mode ID.
key
string
Config key.
value
string
Config value.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
mode
object
Associated config mode.
Update device config
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote session 2022-05-30\",
\"common\": \"{\\\"gripPairsConfig\\\": [1, 4, 2, 3, 6, 7, 9, 8], \\\"controlConfig\\\": [0, 1, 0, 0, 0], \\\"gripSequentialConfig\\\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]\",
\"updateNote\": true,
\"source\": \"guide\",
\"modes\": [
{
\"id\": 1,
\"config\": \"{\\\"gripPairsConfig\\\": [1, 4, 2, 3, 6, 7, 9, 8], \\\"controlConfig\\\": [0, 1, 0, 0, 0], \\\"gripSequentialConfig\\\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]\"
}
]
}"
const url = new URL(
"http://localhost:8000/api/device/1/config"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote session 2022-05-30",
"common": "{\"gripPairsConfig\": [1, 4, 2, 3, 6, 7, 9, 8], \"controlConfig\": [0, 1, 0, 0, 0], \"gripSequentialConfig\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]",
"updateNote": true,
"source": "guide",
"modes": [
{
"id": 1,
"config": "{\"gripPairsConfig\": [1, 4, 2, 3, 6, 7, 9, 8], \"controlConfig\": [0, 1, 0, 0, 0], \"gripSequentialConfig\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]"
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:UPDATE:DEVICE_NOT_FOUND"
}
Example response (422, Invalid config):
{
"message": "Config has some problems and cannot be saved.",
"errors": {
"modes": {
"mode_3": "Config mode 3 does not belong to device 12."
},
"values": {
"common.inputSite": "Invalid value [\"11\"] for key inputSite - contains string values.",
"common.gripsPositions.1.initial": "Invalid value [200,\"100\",\"100\",\"100\",\"100\"] for key gripsPositions.1.initial - contains string values.",
"mode_1.inputSite": "Invalid value [\"11\"] for key inputSite - contains string values.",
"mode_1.gripsPositions.0.initial": "Invalid value [\"200\",\"100\",\"100\",\"100\",\"100\"] for key gripsPositions.1.initial - contains string values."
}
},
"code": "CONFIG:UPDATE:INVALID_CONFIG"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get device config history
requires authentication
For amputees only restore points are returned.
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config/history?restore_point=1&factory_reset_point=1&date_from=1642003200&date_to=1642003200" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"restore_point\": true,
\"factory_reset_point\": false
}"
const url = new URL(
"http://localhost:8000/api/device/1/config/history"
);
const params = {
"restore_point": "1",
"factory_reset_point": "1",
"date_from": "1642003200",
"date_to": "1642003200",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"restore_point": true,
"factory_reset_point": false
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, Normal/compact response):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"user_id": null,
"device_id": 26,
"index": null,
"name": "Rem ratione veniam fugit odit ea et qui.",
"config": "{\"common\":{\"fingerStrength\":[1,500],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[2,30,65,35,16],\"limit\":[41,31,83,62,29]},\"1\":{\"initial\":[7,72,3,50,43],\"limit\":[20,74,77,75,78]},\"2\":{\"initial\":[32,23,49,33,32],\"limit\":[66,91,76,81,72]},\"3\":{\"initial\":[60,21,52,28,13],\"limit\":[64,23,76,79,85]},\"4\":{\"initial\":[10,5,29,1,58],\"limit\":[83,88,81,20,58]},\"5\":{\"initial\":[28,74,3,6,46],\"limit\":[45,81,41,49,58]},\"6\":{\"initial\":[1,16,1,23,28],\"limit\":[56,43,4,94,40]},\"7\":{\"initial\":[45,15,25,9,13],\"limit\":[52,30,94,57,47]},\"8\":{\"initial\":[53,56,7,56,5],\"limit\":[61,84,47,95,38]},\"9\":{\"initial\":[21,14,4,31,49],\"limit\":[30,16,24,77,85]},\"10\":{\"initial\":[9,29,18,9,50],\"limit\":[83,94,36,27,80]},\"11\":{\"initial\":[10,6,6,88,56],\"limit\":[62,69,38,91,83]},\"12\":{\"initial\":[12,49,52,9,57],\"limit\":[84,76,73,18,59]},\"13\":{\"initial\":[5,1,78,53,44],\"limit\":[47,38,93,66,67]}},\"inputSite\":[1]},\"modes\":[{\"id\":3,\"name\":\"Incidunt animi qui doloremque corrupti ut expedita asperiores.\",\"slot\":0,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[300,200],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[40,60,60,100,100,40,30,0,30,20],\"gripPairsConfig\":[4,11,6,2,10,5,13,8],\"gripSequentialConfig\":[255,7,255,1,255,2,9,4,10,255,5,255],\"gripSwitchingMode\":[2],\"holdOpen\":[2000,2500],\"pulseTimings\":[780,260,140,370],\"softGrip\":[0],\"speedControlStrategy\":[0]}},{\"id\":4,\"name\":\"Aut odio sit autem eligendi voluptatem quia aut.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,0],\"coContractionTimings\":[500,400],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[80,60,80,70,100,90,80,0,60,60],\"gripPairsConfig\":[2,11,3,10,4,1,13,9],\"gripSequentialConfig\":[5,255,7,255,2,255,3,1,4,255,9,6],\"gripSwitchingMode\":[1],\"holdOpen\":[1500,2000],\"pulseTimings\":[290,570,670,550],\"softGrip\":[0],\"speedControlStrategy\":[0]}},{\"id\":5,\"name\":\"Impedit esse est voluptatem sequi consequatur.\",\"slot\":2,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[100,100],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[20,70,20,80,80,60,60,90,20,50],\"gripPairsConfig\":[9,1,12,7,10,11,4,5],\"gripSequentialConfig\":[3,4,255,7,9,10,255,255,255,255,13,11],\"gripSwitchingMode\":[1],\"holdOpen\":[2000,2500],\"pulseTimings\":[600,770,290,310],\"softGrip\":[0],\"speedControlStrategy\":[0]}}]}",
"restore_point": 0,
"factory_reset_point": 0,
"source": "configurator",
"changed_by": 50,
"firmware_version_id": null,
"created_at": "2026-09-22T11:24:43.000000Z",
"updated_at": "2026-09-22T11:24:43.000000Z",
"author": {
"id": 50,
"mrn": "3HQMQAR81790076283",
"name": "Dallas Jenkins Jr.",
"email": "1790076283major.walsh@example.net",
"language": "en",
"phone": "1-838-604-2595",
"phone_country": "SL",
"phone_verified_at": null,
"address1": "37454 Kassulke Garden",
"address2": "Lake Erniemouth, CA 20858-8031",
"postal_code": "69570-3646",
"city": "Jast-Barrows",
"country": "GR",
"clinic_name": "North Eleanoreland",
"clinic_location": "723 Shanahan Ranch Apt. 983\nNorth Alfredaburgh, LA 77424-4880",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:43.000000Z",
"updated_at": "2026-09-22T11:24:43.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"entries": [
{
"id": 1,
"config_history_id": 1,
"config_id": 3,
"old_value": "vero",
"new_value": "sint",
"created_at": "2026-09-22T11:24:43.000000Z",
"updated_at": "2026-09-22T11:24:43.000000Z",
"config_entry": {
"id": 3,
"device_id": 34,
"mode_id": null,
"key": "molestiae",
"value": "veniam",
"created_at": "2026-09-22T11:24:43.000000Z",
"updated_at": "2026-09-22T11:24:43.000000Z"
}
}
]
},
{
"id": 3,
"user_id": null,
"device_id": 35,
"index": null,
"name": "Optio tempora expedita aliquam sint deleniti.",
"config": "{\"common\":{\"fingerStrength\":[1,200],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[25,66,7,39,47],\"limit\":[37,94,44,85,49]},\"1\":{\"initial\":[31,32,58,23,4],\"limit\":[49,56,82,75,58]},\"2\":{\"initial\":[46,9,25,4,32],\"limit\":[63,42,30,56,84]},\"3\":{\"initial\":[77,24,38,82,3],\"limit\":[92,26,72,91,92]},\"4\":{\"initial\":[50,1,12,9,6],\"limit\":[86,95,76,30,59]},\"5\":{\"initial\":[12,14,10,23,35],\"limit\":[24,30,64,78,40]},\"6\":{\"initial\":[12,33,11,32,23],\"limit\":[72,54,33,75,56]},\"7\":{\"initial\":[69,40,8,3,27],\"limit\":[76,72,84,50,69]},\"8\":{\"initial\":[62,82,9,90,54],\"limit\":[95,95,64,90,92]},\"9\":{\"initial\":[30,62,9,21,12],\"limit\":[40,62,60,44,44]},\"10\":{\"initial\":[9,4,23,40,83],\"limit\":[28,85,42,77,86]},\"11\":{\"initial\":[72,18,29,47,7],\"limit\":[76,65,60,72,88]},\"12\":{\"initial\":[18,5,18,7,12],\"limit\":[83,94,76,65,54]},\"13\":{\"initial\":[16,86,44,37,25],\"limit\":[24,95,86,94,39]}},\"inputSite\":[1]},\"modes\":[{\"id\":9,\"name\":\"Dolor sunt a et.\",\"slot\":0,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[200,100],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[50,0,100,10,70,80,50,0,40,100],\"gripPairsConfig\":[11,1,3,12,7,2,13,5],\"gripSequentialConfig\":[1,12,9,10,3,2,5,255,11,255,6,7],\"gripSwitchingMode\":[3],\"holdOpen\":[2000,2500],\"pulseTimings\":[900,930,130,60],\"softGrip\":[0],\"speedControlStrategy\":[1]}},{\"id\":10,\"name\":\"Perferendis ipsum quisquam non tenetur quia nostrum.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[400,300],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[100,20,50,20,10,90,30,80,80,90],\"gripPairsConfig\":[10,13,3,2,7,6,4,12],\"gripSequentialConfig\":[9,13,5,4,6,1,11,255,2,255,255,8],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,2000],\"pulseTimings\":[650,490,770,340],\"softGrip\":[1],\"speedControlStrategy\":[1]}},{\"id\":11,\"name\":\"Sed ipsa iste voluptas maiores id voluptatem.\",\"slot\":2,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[200,100],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[60,30,50,50,50,30,100,10,50,90],\"gripPairsConfig\":[1,9,10,11,4,5,3,8],\"gripSequentialConfig\":[6,255,13,4,7,5,1,9,3,255,8,10],\"gripSwitchingMode\":[1],\"holdOpen\":[2000,2500],\"pulseTimings\":[300,790,140,170],\"softGrip\":[1],\"speedControlStrategy\":[0]}}]}",
"restore_point": 1,
"factory_reset_point": 0,
"source": "configurator",
"changed_by": 53,
"firmware_version_id": null,
"created_at": "2026-09-22T11:24:44.000000Z",
"updated_at": "2026-09-22T11:24:44.000000Z",
"author": {
"id": 53,
"mrn": "8GDZZT781790076284",
"name": "Heidi Gutmann",
"email": "1790076284champlin.leopold@example.org",
"language": "en",
"phone": "+16123845199",
"phone_country": "AW",
"phone_verified_at": null,
"address1": "28320 Fay Corners Suite 800",
"address2": "Ashleyland, LA 39560",
"postal_code": "05120",
"city": "Koch-Douglas",
"country": "FR",
"clinic_name": "Cartwrightstad",
"clinic_location": "484 Zulauf Green Apt. 655\nHagenesfurt, AZ 67092",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:44.000000Z",
"updated_at": "2026-09-22T11:24:44.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"entries": [
{
"id": 2,
"config_history_id": 3,
"config_id": 4,
"old_value": "sit",
"new_value": "est",
"created_at": "2026-09-22T11:24:45.000000Z",
"updated_at": "2026-09-22T11:24:45.000000Z",
"config_entry": {
"id": 4,
"device_id": 43,
"mode_id": null,
"key": "provident",
"value": "veniam",
"created_at": "2026-09-22T11:24:45.000000Z",
"updated_at": "2026-09-22T11:24:45.000000Z"
}
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device config",
"code": "CONFIG:HISTORY:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:HISTORY:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Config history entry ID.
device_id
integer
Associated device ID.
index
integer
Config history index.
name
string
Config snapshot name.
config
string
Serialized config data.
restore_point
boolean
Whether this entry is a restore point.
factory_reset_point
boolean
Whether this entry is a factory reset point.
changed_by
integer
ID of the user who made the change.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who made the change.
entries
object[]
Individual config history entries.
notes
object[]
Notes attached to this history entry.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get device config history entry
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config/history/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/history/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 5,
"user_id": null,
"device_id": 44,
"index": null,
"name": "Maxime eligendi libero vitae voluptatem iste.",
"config": "{\"common\":{\"fingerStrength\":[1,100],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[41,2,89,73,35],\"limit\":[65,35,92,77,75]},\"1\":{\"initial\":[12,27,7,14,12],\"limit\":[84,35,18,59,50]},\"2\":{\"initial\":[43,61,56,1,24],\"limit\":[47,88,90,62,80]},\"3\":{\"initial\":[47,58,26,66,40],\"limit\":[68,61,69,84,85]},\"4\":{\"initial\":[64,16,42,13,27],\"limit\":[91,46,60,60,39]},\"5\":{\"initial\":[77,24,17,5,85],\"limit\":[88,40,78,51,85]},\"6\":{\"initial\":[38,44,47,4,6],\"limit\":[38,54,76,16,57]},\"7\":{\"initial\":[10,18,52,69,29],\"limit\":[17,47,94,73,85]},\"8\":{\"initial\":[12,2,50,4,21],\"limit\":[44,70,66,21,63]},\"9\":{\"initial\":[53,19,40,19,19],\"limit\":[89,70,57,55,72]},\"10\":{\"initial\":[9,21,5,15,9],\"limit\":[88,87,25,57,94]},\"11\":{\"initial\":[54,9,15,32,13],\"limit\":[94,90,42,84,73]},\"12\":{\"initial\":[43,8,3,2,5],\"limit\":[67,47,90,86,75]},\"13\":{\"initial\":[68,22,41,9,4],\"limit\":[88,49,82,21,22]}},\"inputSite\":[1]},\"modes\":[{\"id\":15,\"name\":\"Qui rerum porro minus aspernatur aut excepturi quia.\",\"slot\":0,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[400,300],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[60,90,80,10,60,90,20,80,40,10],\"gripPairsConfig\":[2,3,10,7,5,11,12,1],\"gripSequentialConfig\":[3,11,7,13,10,255,9,8,4,1,2,5],\"gripSwitchingMode\":[2],\"holdOpen\":[1500,2000],\"pulseTimings\":[920,410,250,660],\"softGrip\":[0],\"speedControlStrategy\":[1]}},{\"id\":16,\"name\":\"Placeat esse maxime ducimus recusandae aut.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,0],\"coContractionTimings\":[400,200],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[80,50,50,40,100,10,30,70,0,50],\"gripPairsConfig\":[8,12,5,7,11,4,6,9],\"gripSequentialConfig\":[4,255,1,255,2,11,255,255,13,255,12,255],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,2500],\"pulseTimings\":[360,400,530,920],\"softGrip\":[1],\"speedControlStrategy\":[1]}},{\"id\":17,\"name\":\"Et occaecati facilis maxime dicta perferendis est molestias similique.\",\"slot\":2,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[400,100],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[30,90,80,50,100,50,20,100,0,90],\"gripPairsConfig\":[11,12,4,9,3,1,8,6],\"gripSequentialConfig\":[11,4,13,9,3,255,8,6,5,1,12,10],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,1500],\"pulseTimings\":[250,670,630,880],\"softGrip\":[0],\"speedControlStrategy\":[0]}}]}",
"restore_point": 0,
"factory_reset_point": 0,
"source": "configurator",
"changed_by": 55,
"firmware_version_id": null,
"created_at": "2026-09-22T11:24:45.000000Z",
"updated_at": "2026-09-22T11:24:45.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device config",
"code": "CONFIG:HISTORY_ENTRY:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:HISTORY_ENTRY:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG:HISTORY_ENTRY:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config history entry ID.
device_id
integer
Associated device ID.
index
integer
Config history index.
name
string
Config snapshot name.
config
string
Serialized config data.
restore_point
boolean
Whether this entry is a restore point.
factory_reset_point
boolean
Whether this entry is a factory reset point.
changed_by
integer
ID of the user who made the change.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who made the change.
entries
object[]
Individual config history entries.
notes
object[]
Notes attached to this history entry.
Update config history
requires authentication
Returns updated config history in response.
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config/history/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote session 2022-05-30\",
\"restore_point\": true,
\"factory_reset_point\": false
}"
const url = new URL(
"http://localhost:8000/api/device/1/config/history/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote session 2022-05-30",
"restore_point": true,
"factory_reset_point": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 6,
"user_id": null,
"device_id": 48,
"index": null,
"name": "Optio sed repellendus impedit sequi.",
"config": "{\"common\":{\"fingerStrength\":[1,200],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[30,75,50,14,12],\"limit\":[81,80,59,26,66]},\"1\":{\"initial\":[7,13,72,39,33],\"limit\":[23,70,79,44,45]},\"2\":{\"initial\":[7,34,2,1,5],\"limit\":[57,95,47,60,47]},\"3\":{\"initial\":[8,31,5,50,50],\"limit\":[50,52,38,87,59]},\"4\":{\"initial\":[47,23,26,47,81],\"limit\":[79,44,68,94,87]},\"5\":{\"initial\":[13,21,24,18,1],\"limit\":[61,95,37,73,21]},\"6\":{\"initial\":[40,26,7,13,35],\"limit\":[79,30,45,68,86]},\"7\":{\"initial\":[89,16,64,25,82],\"limit\":[95,73,73,32,85]},\"8\":{\"initial\":[60,74,57,37,43],\"limit\":[95,81,63,74,93]},\"9\":{\"initial\":[18,72,12,41,58],\"limit\":[68,75,29,41,79]},\"10\":{\"initial\":[36,65,83,36,33],\"limit\":[46,82,93,43,81]},\"11\":{\"initial\":[73,66,10,25,51],\"limit\":[77,94,24,52,90]},\"12\":{\"initial\":[2,1,2,26,29],\"limit\":[5,95,11,45,53]},\"13\":{\"initial\":[72,51,10,56,52],\"limit\":[83,87,20,71,89]}},\"inputSite\":[1]},\"modes\":[{\"id\":18,\"name\":\"Rerum corporis dolorem et quia neque hic.\",\"slot\":0,\"config\":{\"autoGrasp\":[0,0],\"coContractionTimings\":[100,100],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[20,70,20,90,40,30,100,10,100,50],\"gripPairsConfig\":[1,11,4,8,7,9,6,5],\"gripSequentialConfig\":[2,255,13,11,7,255,1,8,12,6,4,3],\"gripSwitchingMode\":[1],\"holdOpen\":[1500,2500],\"pulseTimings\":[770,570,620,430],\"softGrip\":[0],\"speedControlStrategy\":[0]}},{\"id\":19,\"name\":\"Et soluta est enim possimus libero laboriosam.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[500,400],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[40,20,30,60,70,50,0,90,10,100],\"gripPairsConfig\":[5,9,13,10,4,11,3,1],\"gripSequentialConfig\":[9,4,3,10,7,255,13,255,2,6,255,1],\"gripSwitchingMode\":[2],\"holdOpen\":[2000,2500],\"pulseTimings\":[720,870,880,70],\"softGrip\":[0],\"speedControlStrategy\":[1]}},{\"id\":20,\"name\":\"Aut id id aut in blanditiis rem expedita.\",\"slot\":2,\"config\":{\"autoGrasp\":[0,0],\"coContractionTimings\":[300,100],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[20,50,30,20,60,70,90,40,0,10],\"gripPairsConfig\":[6,9,4,13,11,7,1,5],\"gripSequentialConfig\":[255,9,255,7,8,255,12,6,255,10,13,11],\"gripSwitchingMode\":[1],\"holdOpen\":[2000,2500],\"pulseTimings\":[730,210,170,880],\"softGrip\":[1],\"speedControlStrategy\":[0]}}]}",
"restore_point": 1,
"factory_reset_point": 0,
"source": "configurator",
"changed_by": 56,
"firmware_version_id": null,
"created_at": "2026-09-22T11:24:46.000000Z",
"updated_at": "2026-09-22T11:24:46.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:HISTORY_UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Factory reset point already exists):
{
"message": "Factory reset point does not exist",
"code": "CONFIG:HISTORY_UPDATE:FACTORY_RESET_POINT_ALREADY_EXISTS"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:HISTORY_UPDATE:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG:HISTORY_UPDATE:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config history entry ID.
device_id
integer
Associated device ID.
index
integer
Config history index.
name
string
Config snapshot name.
config
string
Serialized config data.
restore_point
boolean
Whether this entry is a restore point.
factory_reset_point
boolean
Whether this entry is a factory reset point.
changed_by
integer
ID of the user who made the change.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who made the change.
entries
object[]
Individual config history entries.
notes
object[]
Notes attached to this history entry.
Undo single config history change
requires authentication
Returns updated config in response.
Example request:
curl --request DELETE \
"http://localhost:8000/api/device/1/config/history/undo/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/history/undo/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, Normal/compact response):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:UNDO:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:UNDO:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG:UNDO:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Restore config history entry
requires authentication
Restores config from given config history entry (all changes). Sends support ticket if patient is assigned to device, returns config instead.
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config/restore/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/restore/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, Patient not assigned, returns config):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (202):
{
"id": 1,
"sender_id": 57,
"recipient_id": 58,
"device_id": null,
"meeting_date": "2026-09-22 11:24:46",
"meeting_type": "online_meeting",
"contact_email": "magnolia.anderson@okon.com",
"status": "new",
"created_at": "2026-09-22T11:24:47.000000Z",
"updated_at": "2026-09-22T11:24:47.000000Z",
"sender": {
"id": 57,
"mrn": "5Z4C596S1790076286",
"name": "Pearlie Hilpert",
"email": "1790076286quinten14@example.org",
"language": "en",
"phone": "+1-559-621-5467",
"phone_country": "MM",
"phone_verified_at": null,
"address1": "236 Marcia Village",
"address2": "Lake Joeyshire, SD 90529-5498",
"postal_code": "47559-1321",
"city": "Kassulke Group",
"country": "RO",
"clinic_name": "New Rethaton",
"clinic_location": "3489 Marvin Fork\nSouth Daisyborough, MD 24249-5999",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:46.000000Z",
"updated_at": "2026-09-22T11:24:46.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 58,
"mrn": "4ST24PW91790076286",
"name": "Lennie Terry V",
"email": "1790076286salvador.bayer@example.org",
"language": "en",
"phone": "+1 (615) 798-1103",
"phone_country": "SV",
"phone_verified_at": null,
"address1": "1136 Smith Ports Suite 789",
"address2": "Hagenesburgh, WA 92444",
"postal_code": "83598",
"city": "Leuschke, Dickens and Ryan",
"country": "SI",
"clinic_name": "Emelieborough",
"clinic_location": "1827 Eloise Plaza Apt. 691\nBarrowsfort, NE 21241",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:47.000000Z",
"updated_at": "2026-09-22T11:24:47.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": null,
"messages": [
{
"id": 1,
"ticket_id": 1,
"sender_id": 59,
"title": "Prof.",
"content": "Illo id consequatur enim quidem totam.",
"is_read": false,
"created_at": "2026-09-22T11:24:48.000000Z",
"updated_at": "2026-09-22T11:24:48.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:RESTORE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:RESTORE:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG:RESTORE:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Restore to factory reset point
requires authentication
Restores config from the device's factory reset point. Sends a support ticket if the patient is assigned to the device. Returns the array that contains:
config- The factory reset config. It might be updated with current config entries when the restored config does not contain a key or its value is false, but the key is available in the current config, has a non-false value, and is required by the config schema.not_modified- The part of the current config that contains keys which were ignored (because they’re on the ignore list, such as custom grips settings), or were not updated with values from the factory reset config (because the values are the same in both configs, or missing in the factory reset config but present and non-false in the current config). These are included in theconfigto ensure their values remain unchanged and are not replaced with defaults.ticket- Support ticket entity, if patient is assigned, null otherwise.
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config/restore-factory-reset" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/restore-factory-reset"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"config": {
"common": {
"inputSite": [
1
],
"generalHandSettings": false,
"batteryBeep": [
1,
0
],
"emgGains": false,
"autoGrasp": false
},
"modes": [
{
"id": 1,
"name": "Mode 0",
"slot": 0,
"config": {
"gripPairsConfig": false,
"emgThresholds": false,
"emgSpike": false,
"controlMode": false
}
},
{
"id": 1530,
"name": "Mode 1",
"slot": 1,
"config": {
"gripPairsConfig": false,
"emgThresholds": false,
"emgSpike": false,
"controlMode": false
}
},
{
"id": 1531,
"name": "Mode 2",
"slot": 2,
"config": {
"gripPairsConfig": false,
"emgThresholds": false,
"emgSpike": false,
"controlMode": false
}
}
]
},
"not_modified": {
"common": {
"inputSite": [
1
],
"batteryBeep": [
1,
0
],
"generalHandSettings": [
1,
2,
3,
4
]
},
"modes": [
{
"userFeedbackType": false,
"buzzingVolumeSettings": false
},
{
"userFeedbackType": false,
"buzzingVolumeSettings": false
},
{
"userFeedbackType": false,
"buzzingVolumeSettings": false
}
]
},
"ticket": {
"id": 1,
"sender_id": 1,
"recipient_id": 2,
"device_id": 1,
"meeting_date": "2025-07-22T15:00:00.000000Z",
"meeting_type": "none",
"contact_email": null,
"status": "new",
"created_at": "2025-07-22T15:00:00.000000Z",
"updated_at": "2025-07-22T15:00:00.000000Z",
"messages": [
{
"id": 1,
"ticket_id": 1,
"sender_id": 1,
"title": "New config update",
"content": "",
"is_read": false,
"created_at": "2025-07-22T15:00:00.000000Z",
"updated_at": "2025-07-22T15:00:00.000000Z",
"attachments": [
{
"id": 6629,
"ticket_id": 12973,
"ticket_message_id": 6517,
"type": "json",
"title": "Current config",
"attachment": "{\"common\":{},\"modes\":[{\"id\":1,\"name\":\"Mode 0\",\"slot\":0,\"config\":{}},{\"id\":2,\"name\":\"Mode 1\",\"slot\":1,\"config\":{}},{\"id\":3,\"name\":\"Mode 2\",\"slot\":2,\"config\":{}}]}",
"created_at": "2025-07-22T15:00:00.000000Z",
"updated_at": "2025-07-22T15:00:00.000000Z"
},
{
"id": 6630,
"ticket_id": 12973,
"ticket_message_id": 6517,
"type": "json",
"title": "New config",
"attachment": "{\"common\":{},\"modes\":[{\"id\":1,\"name\":\"Mode 0\",\"slot\":0,\"config\":{}},{\"id\":2,\"name\":\"Mode 1\",\"slot\":1,\"config\":{}},{\"id\":3,\"name\":\"Mode 2\",\"slot\":2,\"config\":{}}]}",
"created_at": "2025-07-22T15:00:00.000000Z",
"updated_at": "2025-07-22T15:00:00.000000Z"
}
]
}
]
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:RESTORE_FACTORY_RESET:INSUFFICIENT_PERMISSION"
}
Example response (403, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG:RESTORE_FACTORY_RESET:NO_RESTORE_POINT"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:RESTORE_FACTORY_RESET:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send test config
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config/send" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"description\": \"Fixed problem with grips.\",
\"p2p_session\": 1,
\"updateConfig\": false,
\"common\": \"{\\\"gripPairsConfig\\\": [1, 4, 2, 3, 6, 7, 9, 8], \\\"controlConfig\\\": [0, 1, 0, 0, 0], \\\"gripSequentialConfig\\\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]\",
\"source\": \"guide\",
\"modes\": [
{
\"id\": 1,
\"config\": \"{\\\"gripPairsConfig\\\": [1, 4, 2, 3, 6, 7, 9, 8], \\\"controlConfig\\\": [0, 1, 0, 0, 0], \\\"gripSequentialConfig\\\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]\"
}
]
}"
const url = new URL(
"http://localhost:8000/api/device/1/config/send"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"description": "Fixed problem with grips.",
"p2p_session": 1,
"updateConfig": false,
"common": "{\"gripPairsConfig\": [1, 4, 2, 3, 6, 7, 9, 8], \"controlConfig\": [0, 1, 0, 0, 0], \"gripSequentialConfig\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]",
"source": "guide",
"modes": [
{
"id": 1,
"config": "{\"gripPairsConfig\": [1, 4, 2, 3, 6, 7, 9, 8], \"controlConfig\": [0, 1, 0, 0, 0], \"gripSequentialConfig\": [1, 2, 4, 3, 0, 255, 6, 7, 9, 8, 255, 255]"
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 7,
"sender_id": 68,
"recipient_id": 69,
"device_id": null,
"meeting_date": "2026-09-22 11:24:52",
"meeting_type": "online_meeting",
"contact_email": "hellen72@kerluke.net",
"status": "new",
"created_at": "2026-09-22T11:24:52.000000Z",
"updated_at": "2026-09-22T11:24:52.000000Z",
"sender": {
"id": 68,
"mrn": "8VPGSEHH1790076291",
"name": "Dee Blick",
"email": "1790076291therman@example.net",
"language": "en",
"phone": "+18729765255",
"phone_country": "SC",
"phone_verified_at": null,
"address1": "713 Koelpin Flats",
"address2": "Emilieville, OK 73313-5009",
"postal_code": "21607",
"city": "Corkery, Prosacco and Corwin",
"country": "NL",
"clinic_name": "Lake Amari",
"clinic_location": "610 Thiel Mountain\nHarveyfurt, SC 54083-8258",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:52.000000Z",
"updated_at": "2026-09-22T11:24:52.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 69,
"mrn": "FCPQSKE21790076292",
"name": "Dr. Adonis Yundt",
"email": "1790076292avery88@example.org",
"language": "en",
"phone": "+1.623.513.5558",
"phone_country": "SL",
"phone_verified_at": null,
"address1": "97772 Hill Gateway Suite 265",
"address2": "East Shaun, KY 88231-9568",
"postal_code": "48384-3301",
"city": "Wolf Inc",
"country": "SE",
"clinic_name": "North Freeman",
"clinic_location": "115 Von Fork Apt. 760\nEast Jaleel, NH 41635-9423",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:52.000000Z",
"updated_at": "2026-09-22T11:24:52.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": null,
"messages": [
{
"id": 4,
"ticket_id": 7,
"sender_id": 70,
"title": "Mr.",
"content": "Laudantium sit fugit aut dolorem itaque.",
"is_read": false,
"created_at": "2026-09-22T11:24:54.000000Z",
"updated_at": "2026-09-22T11:24:54.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:SEND:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG:SEND:DEVICE_NOT_FOUND"
}
Example response (422, Device does not have an amputee assigned):
{
"message": "Device does not have an amputee assigned",
"code": "CONFIG:SEND:NO_PATIENT"
}
Example response (422, Invalid P2P session):
{
"message": "Invalid P2P session",
"code": "CONFIG:SEND:INVALID_P2P_SESSION"
}
Example response (422, Invalid config):
{
"message": "Config has some problems and cannot be saved.",
"errors": {
"modes": {
"mode_3": "Config mode 3 does not belong to device 12."
},
"values": {
"common.inputSite": "Invalid value [\"11\"] for key inputSite - contains string values.",
"common.gripsPositions.1.initial": "Invalid value [200,\"100\",\"100\",\"100\",\"100\"] for key gripsPositions.1.initial - contains string values.",
"mode_1.inputSite": "Invalid value [\"11\"] for key inputSite - contains string values.",
"mode_1.gripsPositions.0.initial": "Invalid value [\"200\",\"100\",\"100\",\"100\",\"100\"] for key gripsPositions.1.initial - contains string values."
}
},
"code": "CONFIG:SEND:INVALID_CONFIG"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Convert config
requires authentication
Convert config JSON to match given Firmware Version. Keys are moved between common config and modes.
Example request:
curl --request POST \
"http://localhost:8000/api/config/convert" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"config\": \"[\\\"nobis\\\",\\\"voluptatem\\\"]\",
\"firmware\": 1
}"
const url = new URL(
"http://localhost:8000/api/config/convert"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"config": "[\"nobis\",\"voluptatem\"]",
"firmware": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG:CONVERT:INSUFFICIENT_PERMISSION"
}
Example response (404, Firmware version not found):
{
"message": "Firmware version not found",
"code": "CONFIG:CONVERT:FIRMWARE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get config snapshot
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config-snapshot" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config-snapshot"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"device_id": 65,
"config": "{\"common\":[],\"modes\":[]}",
"custom_grips": "[]",
"created_at": "2026-09-22T11:24:57.000000Z",
"updated_at": "2026-09-22T11:24:57.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device config",
"code": "CONFIG_SNAPSHOT:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_SNAPSHOT:GET:DEVICE_NOT_FOUND"
}
Example response (404, Snapshot not found):
{
"message": "Config snapshot not found",
"code": "CONFIG_SNAPSHOT:GET:SNAPSHOT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update config snapshot
requires authentication
Creates a snapshot of the device's config and custom grips. Replaces any existing snapshot for this device.
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config-snapshot" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config-snapshot"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 2,
"device_id": 67,
"config": "{\"common\":[],\"modes\":[]}",
"custom_grips": "[]",
"created_at": "2026-09-22T11:24:57.000000Z",
"updated_at": "2026-09-22T11:24:57.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "CONFIG_SNAPSHOT:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_SNAPSHOT:UPDATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Config Demo
API endpoints for managing config demos
List config demos
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config/demos?accepted=12" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/demos"
);
const params = {
"accepted": "12",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"user_id": null,
"device_id": 85,
"message_id": 8,
"config": "Ducimus saepe expedita eius nobis.",
"is_accepted": 1,
"notes": "Rerum quo consequatur odit eos explicabo quia.",
"created_at": "2026-09-22T11:25:04.000000Z",
"updated_at": "2026-09-22T11:25:04.000000Z",
"message": {
"id": 8,
"ticket_id": 15,
"sender_id": 92,
"title": "Mr.",
"content": "Aut rem quas velit dolorum impedit quo id.",
"is_read": false,
"created_at": "2026-09-22T11:25:04.000000Z",
"updated_at": "2026-09-22T11:25:04.000000Z"
}
},
{
"id": 2,
"user_id": null,
"device_id": 86,
"message_id": 10,
"config": "Ut quasi iusto tempore voluptate neque.",
"is_accepted": 1,
"notes": "Voluptate placeat magni id error.",
"created_at": "2026-09-22T11:25:07.000000Z",
"updated_at": "2026-09-22T11:25:07.000000Z",
"message": {
"id": 10,
"ticket_id": 18,
"sender_id": 97,
"title": "Dr.",
"content": "Eum molestias consequatur earum maiores ex ex velit.",
"is_read": false,
"created_at": "2026-09-22T11:25:07.000000Z",
"updated_at": "2026-09-22T11:25:07.000000Z"
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config demos",
"code": "CONFIG_DEMO:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_DEMO:LIST:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update config demo
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/device/1/config/demos/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"is_accepted\": false,
\"notes\": \"Something is still not working\"
}"
const url = new URL(
"http://localhost:8000/api/device/1/config/demos/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"is_accepted": false,
"notes": "Something is still not working"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 3,
"user_id": null,
"device_id": 87,
"message_id": 11,
"config": "Excepturi quia harum dolorem pariatur ut iure.",
"is_accepted": 1,
"notes": "Quidem et deserunt vel aut distinctio perferendis vitae.",
"created_at": "2026-09-22T11:25:08.000000Z",
"updated_at": "2026-09-22T11:25:08.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config demos",
"code": "CONFIG_DEMO:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_DEMO:UPDATE:DEVICE_NOT_FOUND"
}
Example response (404, Config demo not found):
{
"message": "Config demo not found",
"code": "CONFIG_DEMO:UPDATE:DEMO_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Config Modes
API endpoints for managing config modes
List config modes
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config-modes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config-modes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 72,
"device_id": 116,
"slot": null,
"name": "Tenetur quis possimus deleniti neque nobis nihil doloribus.",
"active": 1,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z",
"device": {
"id": 116,
"serial": "b808ddd1-63b1-37f3-8b68-b5dbfb0bde56",
"bluetooth_id": "082e1e62-8d0f-36f8-8c44-15692edce049",
"company_id": null,
"model_id": null,
"amputee_id": 110,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z",
"first_config_change_at": null,
"amputee": {
"id": 110,
"mrn": "7KT2CKB81790076313",
"name": "Jasen Kling",
"email": "1790076313johnathan03@example.com",
"language": "en",
"phone": "(830) 299-4331",
"phone_country": "BE",
"phone_verified_at": null,
"address1": "6661 Gwen Locks",
"address2": "South Agustinachester, MT 15403-9247",
"postal_code": "86722-4762",
"city": "Boehm LLC",
"country": "SI",
"clinic_name": "Lake Chandlertown",
"clinic_location": "7676 Parker Turnpike Suite 628\nJarenbury, NE 12182",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:13.000000Z",
"updated_at": "2026-09-22T11:25:13.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
},
{
"id": 73,
"device_id": 118,
"slot": null,
"name": "Officia occaecati voluptas nihil harum enim rerum commodi officia.",
"active": 0,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z",
"config": {}
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list config modes",
"code": "CONFIG_MODES:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_MODES:LIST:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config mode ID.
device_id
integer
Associated device ID.
slot
integer
Mode slot index (0, 1 or 2).
name
string
Mode name.
active
boolean
Whether the mode is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Get config mode
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config-modes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config-modes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 74,
"device_id": 119,
"slot": null,
"name": "Minima atque fugit sed aliquam voluptatem sed.",
"active": 1,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list config modes",
"code": "CONFIG_MODES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_MODES:GET:DEVICE_NOT_FOUND"
}
Example response (404, Config mode not found):
{
"message": "Config mode not found",
"code": "CONFIG_MODES:GET:MODE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config mode ID.
device_id
integer
Associated device ID.
slot
integer
Mode slot index (0, 1 or 2).
name
string
Mode name.
active
boolean
Whether the mode is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create config mode
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config-modes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"slot\": 0,
\"name\": \"Sport mode\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/device/1/config-modes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"slot": 0,
"name": "Sport mode",
"active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 75,
"device_id": 120,
"slot": null,
"name": "Ex qui error eligendi sed aperiam.",
"active": 1,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create config modes",
"code": "CONFIG_MODES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_MODES:CREATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config mode ID.
device_id
integer
Associated device ID.
slot
integer
Mode slot index (0, 1 or 2).
name
string
Mode name.
active
boolean
Whether the mode is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update config mode
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/device/1/config-modes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"slot\": 0,
\"name\": \"Sport mode\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/device/1/config-modes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"slot": 0,
"name": "Sport mode",
"active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 76,
"device_id": 121,
"slot": null,
"name": "Maiores eos est et dolor id voluptatum eligendi.",
"active": 1,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update config mode",
"code": "CONFIG_MODES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_MODES:UPDATE:DEVICE_NOT_FOUND"
}
Example response (404, Config mode not found):
{
"message": "Config mode not found",
"code": "CONFIG_MODES:UPDATE:MODE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config mode ID.
device_id
integer
Associated device ID.
slot
integer
Mode slot index (0, 1 or 2).
name
string
Mode name.
active
boolean
Whether the mode is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Copy device config from template
requires authentication
Copy config template into selected config mode. Sends support ticket if patient is assigned to device, returns config instead.
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config-modes/1/from-template/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config-modes/1/from-template/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, Patient not assigned, returns config):
{
"common": {
"gripPairsConfig": [
1,
4,
2,
3,
6,
7,
9,
8
],
"controlConfig": [
0,
1,
0,
0,
0
],
"emgThresholds": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"interval": [
100
],
"gripSequentialConfig": [
1,
2,
4,
3,
0,
255,
6,
7,
9,
8,
255,
255
]
},
"modes": [
{
"id": 100,
"name": "Mode 1",
"slot": 0,
"config": {
"interval": [
300
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 101,
"name": "Mode 2",
"slot": 1,
"config": {
"interval": [
400
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
},
{
"id": 102,
"name": "Mode 3",
"slot": 2,
"config": {
"interval": [
500
],
"fingerStrength": [
1,
100
],
"autoGrasp": [
0,
100
],
"emgSpike": [
0,
300
]
}
}
]
}
Example response (202):
{
"id": 21,
"sender_id": 112,
"recipient_id": 113,
"device_id": null,
"meeting_date": "2026-09-22 11:25:15",
"meeting_type": "online_meeting",
"contact_email": "samson89@gmail.com",
"status": "new",
"created_at": "2026-09-22T11:25:15.000000Z",
"updated_at": "2026-09-22T11:25:15.000000Z",
"sender": {
"id": 112,
"mrn": "ZMBVC8BG1790076314",
"name": "Jess Morissette",
"email": "1790076314langosh.patrick@example.net",
"language": "en",
"phone": "+1.720.229.0716",
"phone_country": "MU",
"phone_verified_at": null,
"address1": "71899 Lucie Mall Suite 781",
"address2": "West Cole, OK 44799",
"postal_code": "83181",
"city": "Rogahn-Schumm",
"country": "IN",
"clinic_name": "Kraighaven",
"clinic_location": "10028 Leon Meadows\nOrvilleville, MS 10766",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:14.000000Z",
"updated_at": "2026-09-22T11:25:14.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 113,
"mrn": "4JZ8ARET1790076315",
"name": "Gilda Volkman",
"email": "1790076315zgrady@example.com",
"language": "en",
"phone": "681.938.2270",
"phone_country": "BL",
"phone_verified_at": null,
"address1": "4639 Gideon Coves",
"address2": "East Robert, NJ 21406-1626",
"postal_code": "53394",
"city": "Boehm-Franecki",
"country": "GB",
"clinic_name": "South Adolfo",
"clinic_location": "6327 Colten Shoals Apt. 500\nKristyborough, IN 54851",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:15.000000Z",
"updated_at": "2026-09-22T11:25:15.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": null,
"messages": [
{
"id": 12,
"ticket_id": 21,
"sender_id": 114,
"title": "Mr.",
"content": "Qui accusamus adipisci provident est voluptas nihil autem.",
"is_read": false,
"created_at": "2026-09-22T11:25:17.000000Z",
"updated_at": "2026-09-22T11:25:17.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update config mode",
"code": "CONFIG_MODES:COPY_TEMPLATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_MODES:COPY_TEMPLATE:DEVICE_NOT_FOUND"
}
Example response (404, Config mode not found):
{
"message": "Config mode not found",
"code": "CONFIG_MODES:COPY_TEMPLATE:MODE_NOT_FOUND"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_MODES:COPY_TEMPLATE:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Config Notes
API endpoints for config history notes
Get config entry notes list
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config/1/notes?user=1&type=public" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/1/notes"
);
const params = {
"user": "1",
"type": "public",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"config_history_id": 7,
"user_id": 81,
"note": "Omnis sit quos aut et commodi.",
"type": "public",
"created_at": "2026-09-22T11:24:59.000000Z",
"updated_at": "2026-09-22T11:24:59.000000Z",
"author": {
"id": 81,
"mrn": "NVEXBGQZ1790076298",
"name": "Irving Kertzmann",
"email": "1790076298vkoelpin@example.org",
"language": "en",
"phone": "352-914-5726",
"phone_country": "MC",
"phone_verified_at": null,
"address1": "38627 Heber Motorway",
"address2": "West Katarinaton, WI 62721-6651",
"postal_code": "44611",
"city": "Gerlach-Predovic",
"country": "HU",
"clinic_name": "North Friedrich",
"clinic_location": "34058 Odell Pike\nGoldenton, DE 13361",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:58.000000Z",
"updated_at": "2026-09-22T11:24:58.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
},
{
"id": 2,
"config_history_id": 8,
"user_id": 83,
"note": "Eaque dignissimos praesentium fugit ratione.",
"type": "public",
"created_at": "2026-09-22T11:25:00.000000Z",
"updated_at": "2026-09-22T11:25:00.000000Z",
"author": {
"id": 83,
"mrn": "JF9ELBY21790076299",
"name": "Prof. Lowell Zemlak I",
"email": "1790076299eileen66@example.org",
"language": "en",
"phone": "(442) 560-7170",
"phone_country": "GB",
"phone_verified_at": null,
"address1": "59334 Schowalter Oval Suite 193",
"address2": "Labadieburgh, OR 54289",
"postal_code": "37112",
"city": "Mosciski, Hand and Reynolds",
"country": "GR",
"clinic_name": "Karlberg",
"clinic_location": "648 Taylor Forks Suite 019\nSmithamton, WI 73216",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:59.000000Z",
"updated_at": "2026-09-22T11:24:59.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config notes",
"code": "CONFIG_NOTES:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_NOTES:LIST:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG_NOTES:LIST:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Note ID.
config_history_id
integer
Associated config history entry ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
type
string
Note visibility.
Must be one of:publicprivate
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get config entry note
requires authentication
Returns single config history entry note in response.
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/config/1/notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/1/notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 3,
"config_history_id": 9,
"user_id": 85,
"note": "Libero earum vitae et sapiente.",
"type": "public",
"created_at": "2026-09-22T11:25:01.000000Z",
"updated_at": "2026-09-22T11:25:01.000000Z",
"author": {
"id": 85,
"mrn": "QKJMJXT71790076300",
"name": "Ressie Marvin",
"email": "1790076300hilma84@example.com",
"language": "en",
"phone": "+1-843-273-2855",
"phone_country": "VU",
"phone_verified_at": null,
"address1": "6035 Montana Point Apt. 405",
"address2": "North Princesschester, KY 37609-1060",
"postal_code": "44460-9673",
"city": "Powlowski, Lockman and Fay",
"country": "BE",
"clinic_name": "Lake Keara",
"clinic_location": "8042 Madilyn Run\nWest Brando, OK 75755",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:00.000000Z",
"updated_at": "2026-09-22T11:25:00.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config notes",
"code": "CONFIG_NOTES:GET_ENTRY:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_NOTES:GET_ENTRY:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG_NOTES:GET_ENTRY:HISTORY_ENTRY_NOT_FOUND"
}
Example response (404, Config history note not found):
{
"message": "Config history note not found",
"code": "CONFIG_NOTES:GET_ENTRY:HISTORY_NOTE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Note ID.
config_history_id
integer
Associated config history entry ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
type
string
Note visibility.
Must be one of:publicprivate
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
Create config entry note
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/config/1/notes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"note\": \"Eveniet ut soluta consequatur veniam.\",
\"type\": \"public\"
}"
const url = new URL(
"http://localhost:8000/api/device/1/config/1/notes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"note": "Eveniet ut soluta consequatur veniam.",
"type": "public"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 4,
"config_history_id": 10,
"user_id": 87,
"note": "Suscipit explicabo dicta cum sint.",
"type": "public",
"created_at": "2026-09-22T11:25:02.000000Z",
"updated_at": "2026-09-22T11:25:02.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to add config notes",
"code": "CONFIG_NOTES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_NOTES:CREATE:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG_NOTES:CREATE:HISTORY_ENTRY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Note ID.
config_history_id
integer
Associated config history entry ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
type
string
Note visibility.
Must be one of:publicprivate
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
Delete config note
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/device/1/config/1/notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/config/1/notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Config history note deleted",
"code": "CONFIG_NOTES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete config notes",
"code": "CONFIG_NOTES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CONFIG_NOTES:DELETE:DEVICE_NOT_FOUND"
}
Example response (404, Config history entry not found):
{
"message": "Config history entry not found",
"code": "CONFIG_NOTES:DELETE:HISTORY_ENTRY_NOT_FOUND"
}
Example response (404, Config history note not found):
{
"message": "Config history note not found",
"code": "CONFIG_NOTES:DELETE:HISTORY_NOTE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Config Schema
API endpoints for config schema management
Get config schema
requires authentication
Returns list of config schema entries for given firmware version.
Example request:
curl --request GET \
--get "http://localhost:8000/api/versions/firmware/1/schema?filter=modes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/firmware/1/schema"
);
const params = {
"filter": "modes",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"firmware_id": 7,
"key": "ipsum",
"is_common": 0,
"type": "firmware",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
},
{
"id": 2,
"firmware_id": 9,
"key": "aut",
"is_common": 0,
"type": "firmware",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view config schema",
"code": "CONFIG_SCHEMA:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Firmware version not found):
{
"message": "Firmware version not found",
"code": "CONFIG_SCHEMA:GET:FIRMWARE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config schema ID.
firmware_id
integer
Associated firmware version ID.
key
string
Config schema key.
is_common
boolean
Whether this key is shared across all modes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
firmware
object
Associated firmware version.
Add config schema
requires authentication
Add one or many config schema entries. Each entry is one key in config. Body of this request is simple array of objects:
[
{"key": "key_name", "is_common": 1},
{"key": "another_name", "is_common": 0},
...
]
Example request:
curl --request POST \
"http://localhost:8000/api/versions/firmware/nobis/schema" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "[
{
\"key\": \"gripsPosition.0.initial\",
\"is_common\": 1,
\"type\": \"firmware\"
}
]"
const url = new URL(
"http://localhost:8000/api/versions/firmware/nobis/schema"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = [
{
"key": "gripsPosition.0.initial",
"is_common": 1,
"type": "firmware"
}
];
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
[
{
"id": 3,
"firmware_id": 11,
"key": "aut",
"is_common": 0,
"type": "firmware",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
},
{
"id": 4,
"firmware_id": 13,
"key": "dicta",
"is_common": 1,
"type": "firmware",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage config schema",
"code": "CONFIG_SCHEMA:ADD:INSUFFICIENT_PERMISSION"
}
Example response (404, Firmware version not found):
{
"message": "Firmware version not found",
"code": "CONFIG_SCHEMA:ADD:FIRMWARE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config schema ID.
firmware_id
integer
Associated firmware version ID.
key
string
Config schema key.
is_common
boolean
Whether this key is shared across all modes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
firmware
object
Associated firmware version.
Delete config schema
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/versions/firmware/1/schema/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/firmware/1/schema/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Config schema entry deleted",
"code": "CONFIG_SCHEMA:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage config schema",
"code": "CONFIG_SCHEMA:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Firmware version not found):
{
"message": "Firmware version not found",
"code": "CONFIG_SCHEMA:DELETE:FIRMWARE_NOT_FOUND"
}
Example response (404, Config schema entry not found):
{
"message": "Config schema entry not found",
"code": "CONFIG_SCHEMA:DELETE:SCHEMA_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Config Templates
API endpoints for managing config templates
Get config templates list
requires authentication
Entries where author is present are private and owned by its author. Entries where author is null should be considered as global templates prepared by Aether team.
Example request:
curl --request GET \
--get "http://localhost:8000/api/config/templates?search=sport&author=1&scope=me" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates"
);
const params = {
"search": "sport",
"author": "1",
"scope": "me",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "Sint illo necessitatibus voluptas assumenda quia voluptate perferendis.",
"description": "Optio error nemo velit qui.",
"author_id": 101,
"company_id": null,
"config": "{\"autoGrasp\":[1,100],\"coContractionTimings\":[500,200],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[90,60,100,50,90,0,80,80,10,20],\"gripPairsConfig\":[4,1,9,13,7,8,10,2],\"gripSequentialConfig\":[255,1,10,255,7,8,12,6,255,5,13,255],\"gripSwitchingMode\":[1],\"holdOpen\":[2000,2500],\"pulseTimings\":[700,640,180,490],\"softGrip\":[0],\"speedControlStrategy\":[0]}",
"created_at": "2026-09-22T11:25:09.000000Z",
"updated_at": "2026-09-22T11:25:09.000000Z",
"author": {
"id": 101,
"mrn": "LMBUXXWC1790076309",
"name": "Abraham Brekke",
"email": "1790076309elenora80@example.org",
"language": "en",
"phone": "1-785-472-0820",
"phone_country": "GQ",
"phone_verified_at": null,
"address1": "854 McGlynn Loop",
"address2": "Kylamouth, AZ 98324-0961",
"postal_code": "12238",
"city": "Morissette, Welch and Lind",
"country": "MT",
"clinic_name": "Owenstad",
"clinic_location": "3629 Jacobi Key\nNyafort, NE 23541-9553",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:09.000000Z",
"updated_at": "2026-09-22T11:25:09.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
},
{
"id": 2,
"name": "Et assumenda minus rerum veritatis natus minima corporis.",
"description": "Iure molestiae facere architecto.",
"author_id": 102,
"company_id": null,
"config": "{\"autoGrasp\":[1,0],\"coContractionTimings\":[500,500],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[100,50,50,10,50,20,40,0,60,0],\"gripPairsConfig\":[11,13,8,2,9,7,12,5],\"gripSequentialConfig\":[4,255,6,13,2,11,9,8,7,255,255,3],\"gripSwitchingMode\":[2],\"holdOpen\":[1500,2000],\"pulseTimings\":[500,150,820,680],\"softGrip\":[1],\"speedControlStrategy\":[0]}",
"created_at": "2026-09-22T11:25:09.000000Z",
"updated_at": "2026-09-22T11:25:09.000000Z",
"author": {
"id": 102,
"mrn": "3XELRW6K1790076309",
"name": "Adrienne Bogisich",
"email": "1790076309skiles.geovany@example.net",
"language": "en",
"phone": "971.619.2798",
"phone_country": "SY",
"phone_verified_at": null,
"address1": "59776 Yolanda Freeway Suite 385",
"address2": "Lake Revahaven, NV 55304",
"postal_code": "85971-6533",
"city": "Blanda-Nikolaus",
"country": "HR",
"clinic_name": "Maggiohaven",
"clinic_location": "3311 Trevor Corner Apt. 929\nPort Harold, SD 39383",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:09.000000Z",
"updated_at": "2026-09-22T11:25:09.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list config templates",
"code": "CONFIG_TEMPLATES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Config template ID.
name
string
Template name.
description
string
Template description.
author_id
integer
ID of the user who created the template.
company_id
integer
Associated company ID.
config
string
Serialized config data.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who created the template.
notes
object[]
Notes attached to this template.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get config template
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/config/templates/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 3,
"name": "Deleniti necessitatibus architecto debitis perspiciatis quo animi.",
"description": "Eum corrupti facere reprehenderit deleniti omnis veniam ut.",
"author_id": 103,
"company_id": null,
"config": "{\"autoGrasp\":[1,0],\"coContractionTimings\":[500,300],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[60,100,20,50,80,100,20,30,10,70],\"gripPairsConfig\":[7,8,11,12,3,9,1,4],\"gripSequentialConfig\":[255,12,11,7,2,3,8,255,9,255,5,10],\"gripSwitchingMode\":[2],\"holdOpen\":[2000,2500],\"pulseTimings\":[280,770,460,70],\"softGrip\":[1],\"speedControlStrategy\":[0]}",
"created_at": "2026-09-22T11:25:10.000000Z",
"updated_at": "2026-09-22T11:25:10.000000Z",
"author": {
"id": 103,
"mrn": "KMJMDW351790076309",
"name": "Jordan Halvorson II",
"email": "1790076309cwaters@example.org",
"language": "en",
"phone": "(636) 358-4143",
"phone_country": "MN",
"phone_verified_at": null,
"address1": "964 Parker Station",
"address2": "McClureport, WI 96846-9279",
"postal_code": "84238",
"city": "Nikolaus, Dach and Beer",
"country": "ES",
"clinic_name": "Robelborough",
"clinic_location": "7123 Krajcik Viaduct\nSallyburgh, VA 54267",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:10.000000Z",
"updated_at": "2026-09-22T11:25:10.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view config template",
"code": "CONFIG_TEMPLATES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATES:GET:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config template ID.
name
string
Template name.
description
string
Template description.
author_id
integer
ID of the user who created the template.
company_id
integer
Associated company ID.
config
string
Serialized config data.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who created the template.
notes
object[]
Notes attached to this template.
Create new config template
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/config/templates" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Default config for Aether Zeus\",
\"description\": \"Description of the config template.\",
\"owner\": \"company\",
\"author\": 1,
\"config\": \"{\\\"param_1\\\": [100, 200], \\\"param_2\\\": [100, 200, 300]}\"
}"
const url = new URL(
"http://localhost:8000/api/config/templates"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Default config for Aether Zeus",
"description": "Description of the config template.",
"owner": "company",
"author": 1,
"config": "{\"param_1\": [100, 200], \"param_2\": [100, 200, 300]}"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"name": "Debitis odit nihil qui nesciunt aut.",
"description": "Suscipit nam repudiandae ut voluptate tempora.",
"author_id": 104,
"company_id": null,
"config": "{\"autoGrasp\":[1,100],\"coContractionTimings\":[500,200],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[20,70,60,0,60,50,20,100,20,70],\"gripPairsConfig\":[2,7,10,6,5,12,1,4],\"gripSequentialConfig\":[10,7,255,255,255,255,9,255,13,2,11,255],\"gripSwitchingMode\":[2],\"holdOpen\":[1500,2000],\"pulseTimings\":[790,830,950,570],\"softGrip\":[0],\"speedControlStrategy\":[1]}",
"created_at": "2026-09-22T11:25:11.000000Z",
"updated_at": "2026-09-22T11:25:11.000000Z",
"author": {
"id": 104,
"mrn": "2UREGLNN1790076310",
"name": "Tyra McKenzie",
"email": "1790076310casper86@example.com",
"language": "en",
"phone": "+1 (847) 760-0481",
"phone_country": "DO",
"phone_verified_at": null,
"address1": "601 Walsh Keys Apt. 799",
"address2": "New Declanfort, NE 02843-7260",
"postal_code": "54238",
"city": "Cruickshank-Trantow",
"country": "CY",
"clinic_name": "Port Icieport",
"clinic_location": "85736 Zemlak Wall\nHyatthaven, WY 16818-4674",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:10.000000Z",
"updated_at": "2026-09-22T11:25:10.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create config template",
"code": "CONFIG_TEMPLATES:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config template ID.
name
string
Template name.
description
string
Template description.
author_id
integer
ID of the user who created the template.
company_id
integer
Associated company ID.
config
string
Serialized config data.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who created the template.
notes
object[]
Notes attached to this template.
Update config template
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/config/templates/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Default config for Aether Zeus\",
\"description\": \"Description of the config template.\",
\"owner\": \"company\",
\"author\": 1,
\"config\": \"{\\\"param_1\\\": [100, 200], \\\"param_2\\\": [100, 200, 300]}\"
}"
const url = new URL(
"http://localhost:8000/api/config/templates/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Default config for Aether Zeus",
"description": "Description of the config template.",
"owner": "company",
"author": 1,
"config": "{\"param_1\": [100, 200], \"param_2\": [100, 200, 300]}"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 5,
"name": "Unde qui ut alias libero.",
"description": "Est perferendis tempore suscipit quae et quas.",
"author_id": 105,
"company_id": null,
"config": "{\"autoGrasp\":[0,0],\"coContractionTimings\":[500,100],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[0,70,20,90,80,30,0,20,40,40],\"gripPairsConfig\":[4,10,9,3,8,2,11,13],\"gripSequentialConfig\":[4,9,10,255,11,2,1,255,12,7,13,255],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,2000],\"pulseTimings\":[490,1000,990,380],\"softGrip\":[0],\"speedControlStrategy\":[1]}",
"created_at": "2026-09-22T11:25:11.000000Z",
"updated_at": "2026-09-22T11:25:11.000000Z",
"author": {
"id": 105,
"mrn": "5487X9JV1790076311",
"name": "Dr. Elody Cummings Sr.",
"email": "1790076311isabella27@example.net",
"language": "en",
"phone": "(541) 242-6124",
"phone_country": "US",
"phone_verified_at": null,
"address1": "666 Schulist Mills",
"address2": "Alexastad, IA 64968",
"postal_code": "22768-4148",
"city": "Denesik PLC",
"country": "LV",
"clinic_name": "East Raulstad",
"clinic_location": "9486 Fritsch Lake\nDustymouth, MS 05130",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:11.000000Z",
"updated_at": "2026-09-22T11:25:11.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update config template",
"code": "CONFIG_TEMPLATES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATES:UPDATE:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Config template ID.
name
string
Template name.
description
string
Template description.
author_id
integer
ID of the user who created the template.
company_id
integer
Associated company ID.
config
string
Serialized config data.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who created the template.
notes
object[]
Notes attached to this template.
Delete config template
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/config/templates/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Config template deleted",
"code": "CONFIG_TEMPLATES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete config template",
"code": "CONFIG_TEMPLATES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATES:DELETE:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Config Templates Notes
API endpoints for config templates notes
Get config templates notes list
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/config/templates/1/notes?user=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates/1/notes"
);
const params = {
"user": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"template_id": 6,
"user_id": 106,
"note": "Non numquam cum quasi.",
"created_at": "2026-09-22T11:25:12.000000Z",
"updated_at": "2026-09-22T11:25:12.000000Z",
"author": {
"id": 106,
"mrn": "PMQFMLZ41790076311",
"name": "Heaven Stiedemann",
"email": "1790076311ellie80@example.com",
"language": "en",
"phone": "(720) 744-8540",
"phone_country": "PG",
"phone_verified_at": null,
"address1": "1595 Schumm Harbors",
"address2": "Lake Gregoriabury, MA 57419",
"postal_code": "87020",
"city": "Padberg and Sons",
"country": "SE",
"clinic_name": "Lake Grace",
"clinic_location": "806 Abbie Course Apt. 252\nNorth Constancemouth, MD 03997-3354",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:11.000000Z",
"updated_at": "2026-09-22T11:25:11.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
},
{
"id": 2,
"template_id": 7,
"user_id": 107,
"note": "Et laborum adipisci porro et quia.",
"created_at": "2026-09-22T11:25:12.000000Z",
"updated_at": "2026-09-22T11:25:12.000000Z",
"author": {
"id": 107,
"mrn": "TVCMFLEQ1790076312",
"name": "Scotty Pfeffer",
"email": "1790076312oklocko@example.org",
"language": "en",
"phone": "+1 (251) 669-9096",
"phone_country": "MW",
"phone_verified_at": null,
"address1": "925 Pacocha Stravenue Suite 950",
"address2": "New Hunter, NV 16133",
"postal_code": "76407-9785",
"city": "Welch-Price",
"country": "US",
"clinic_name": "Torphymouth",
"clinic_location": "378 Heidi Plain\nNorth Maegan, NY 25440",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:12.000000Z",
"updated_at": "2026-09-22T11:25:12.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config templates notes",
"code": "CONFIG_TEMPLATE_NOTES:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATE_NOTES:LIST:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Note ID.
template_id
integer
Associated config template ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get config template note
requires authentication
Returns single config template note in response.
Example request:
curl --request GET \
--get "http://localhost:8000/api/config/templates/1/notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates/1/notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 3,
"template_id": 8,
"user_id": 108,
"note": "Aut et neque omnis.",
"created_at": "2026-09-22T11:25:13.000000Z",
"updated_at": "2026-09-22T11:25:13.000000Z",
"author": {
"id": 108,
"mrn": "WJABGBL61790076312",
"name": "Bruce Schulist Sr.",
"email": "1790076312conor.upton@example.org",
"language": "en",
"phone": "+1 (620) 829-1867",
"phone_country": "YE",
"phone_verified_at": null,
"address1": "8292 Dickinson Center Suite 015",
"address2": "West Westleyhaven, IN 62717-4204",
"postal_code": "90573-6535",
"city": "Schmeler-Paucek",
"country": "US",
"clinic_name": "Helmerfort",
"clinic_location": "98564 Purdy Canyon Suite 596\nRaetown, NM 72461",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:12.000000Z",
"updated_at": "2026-09-22T11:25:12.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access config templates notes",
"code": "CONFIG_TEMPLATE_NOTES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATE_NOTES:GET:TEMPLATE_NOT_FOUND"
}
Example response (404, Config template note not found):
{
"message": "Config template note not found",
"code": "CONFIG_TEMPLATE_NOTES:GET:NOTE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Note ID.
template_id
integer
Associated config template ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
Create new config template note
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/config/templates/1/notes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"note\": \"Repellendus repellat aut distinctio doloribus et sunt.\"
}"
const url = new URL(
"http://localhost:8000/api/config/templates/1/notes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"note": "Repellendus repellat aut distinctio doloribus et sunt."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"template_id": 9,
"user_id": 109,
"note": "Tempore magnam eos consequatur eum blanditiis mollitia omnis.",
"created_at": "2026-09-22T11:25:13.000000Z",
"updated_at": "2026-09-22T11:25:13.000000Z",
"author": {
"id": 109,
"mrn": "K7C2AF481790076313",
"name": "Burnice Hagenes",
"email": "1790076313jdaugherty@example.com",
"language": "en",
"phone": "857-221-1309",
"phone_country": "MM",
"phone_verified_at": null,
"address1": "622 Reynolds Prairie",
"address2": "Mertztown, KS 98883",
"postal_code": "79948-8813",
"city": "Hudson-Boyer",
"country": "LV",
"clinic_name": "Port Lazaroborough",
"clinic_location": "666 Lind Tunnel Apt. 485\nTorphytown, LA 53382-2497",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:13.000000Z",
"updated_at": "2026-09-22T11:25:13.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to add config templates notes",
"code": "CONFIG_TEMPLATE_NOTES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATE_NOTES:CREATE:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Note ID.
template_id
integer
Associated config template ID.
user_id
integer
ID of the user who wrote the note.
note
string
Note content.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who wrote the note.
Delete config template note
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/config/templates/1/notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/config/templates/1/notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Config template note deleted",
"code": "CONFIG_TEMPLATE_NOTES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete config templates notes",
"code": "CONFIG_TEMPLATE_NOTES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Config template not found):
{
"message": "Config template not found",
"code": "CONFIG_TEMPLATE_NOTES:DELETE:TEMPLATE_NOT_FOUND"
}
Example response (404, Config template note not found):
{
"message": "Config template note not found",
"code": "CONFIG_TEMPLATE_NOTES:DELETE:NOTE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Custom Grips
API endpoints for custom grips management
List custom grips templates
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/custom-grips-templates" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/custom-grips-templates"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"user_id": 260,
"name": "natasha12",
"initial_position": "[50, 50, 50, 50, 50]",
"limit_position": "[900, 900, 900, 900, 900]",
"active_fingers": "[0, 1, 1, 1, 1]",
"created_at": "2026-09-22T11:26:31.000000Z",
"updated_at": "2026-09-22T11:26:31.000000Z"
},
{
"id": 2,
"user_id": 261,
"name": "pyost",
"initial_position": "[50, 50, 50, 50, 50]",
"limit_position": "[900, 900, 900, 900, 900]",
"active_fingers": "[0, 1, 1, 1, 1]",
"created_at": "2026-09-22T11:26:31.000000Z",
"updated_at": "2026-09-22T11:26:31.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips templates",
"code": "CUSTOM_GRIPS_TEMPLATES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Custom grip template ID.
user_id
integer
Owner user ID.
name
string
Template name.
initial_position
string
Initial finger positions.
limit_position
string
Limit finger positions.
active_fingers
string
Active fingers configuration.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create custom grip template
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/custom-grips-templates" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Custom Grip Template 1\",
\"initial_position\": \"[50, 50, 50, 50, 50]\",
\"limit_position\": \"[900, 900, 900, 900, 900]\",
\"active_fingers\": \"[0, 1, 1, 1, 1]\"
}"
const url = new URL(
"http://localhost:8000/api/custom-grips-templates"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Custom Grip Template 1",
"initial_position": "[50, 50, 50, 50, 50]",
"limit_position": "[900, 900, 900, 900, 900]",
"active_fingers": "[0, 1, 1, 1, 1]"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"user_id": 262,
"name": "philip.ritchie",
"initial_position": "[50, 50, 50, 50, 50]",
"limit_position": "[900, 900, 900, 900, 900]",
"active_fingers": "[0, 1, 1, 1, 1]",
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips templates",
"code": "CUSTOM_GRIPS_TEMPLATES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Custom grip template name in use):
{
"message": "Custom grip template name already in use",
"code": "CUSTOM_GRIPS_TEMPLATES:CREATE:NAME_IN_USE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Custom grip template ID.
user_id
integer
Owner user ID.
name
string
Template name.
initial_position
string
Initial finger positions.
limit_position
string
Limit finger positions.
active_fingers
string
Active fingers configuration.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete custom grip template
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/custom-grips-templates/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/custom-grips-templates/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Custom grip deleted",
"code": "CUSTOM_GRIPS_TEMPLATES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips templates",
"code": "CUSTOM_GRIPS_TEMPLATES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Custom grip template not found):
{
"message": "Custom grip template not found",
"code": "CUSTOM_GRIPS_TEMPLATES:DELETE:TEMPLATE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List custom grips
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/custom-grips" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/custom-grips"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"device_id": 143,
"name": "flatley.blake",
"opposed": 1,
"grip_number": 0,
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
},
{
"id": 2,
"device_id": 144,
"name": "davis.santina",
"opposed": 1,
"grip_number": 0,
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view custom grips",
"code": "CUSTOM_GRIPS:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CUSTOM_GRIPS:LIST:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Custom grip ID.
device_id
integer
Associated device ID.
name
string
Custom grip name.
opposed
boolean
Whether the grip is opposed.
grip_number
integer
Grip slot number.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create custom grip
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/custom-grips" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Custom Grip 1\",
\"opposed\": true,
\"grip_number\": 1
}"
const url = new URL(
"http://localhost:8000/api/device/1/custom-grips"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Custom Grip 1",
"opposed": true,
"grip_number": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"device_id": 145,
"name": "victor.schultz",
"opposed": 1,
"grip_number": 0,
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips",
"code": "CUSTOM_GRIPS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Custom grip name in use):
{
"message": "Custom grip name already in use",
"code": "CUSTOM_GRIPS:CREATE:NAME_IN_USE"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CUSTOM_GRIPS:CREATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Custom grip ID.
device_id
integer
Associated device ID.
name
string
Custom grip name.
opposed
boolean
Whether the grip is opposed.
grip_number
integer
Grip slot number.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update custom grip
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/device/1/custom-grips/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Custom Grip 1\",
\"opposed\": true,
\"grip_number\": 1
}"
const url = new URL(
"http://localhost:8000/api/device/1/custom-grips/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Custom Grip 1",
"opposed": true,
"grip_number": 1
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"device_id": 146,
"name": "rubie.grady",
"opposed": 1,
"grip_number": 0,
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips",
"code": "CUSTOM_GRIPS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Custom grip name in use):
{
"message": "Custom grip name already in use",
"code": "CUSTOM_GRIPS:UPDATE:NAME_IN_USE"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CUSTOM_GRIPS:UPDATE:DEVICE_NOT_FOUND"
}
Example response (404, Custom grip not found):
{
"message": "Custom grip not found",
"code": "CUSTOM_GRIPS:UPDATE:GRIP_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Custom grip ID.
device_id
integer
Associated device ID.
name
string
Custom grip name.
opposed
boolean
Whether the grip is opposed.
grip_number
integer
Grip slot number.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete custom grip
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/device/1/custom-grips/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/custom-grips/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Custom grip template deleted",
"code": "CUSTOM_GRIPS:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage custom grips",
"code": "CUSTOM_GRIPS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "CUSTOM_GRIPS:DELETE:DEVICE_NOT_FOUND"
}
Example response (404, Custom grip not found):
{
"message": "Custom grip not found",
"code": "CUSTOM_GRIPS:DELETE:GRIP_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Device Measurements
API endpoints for device measurement history
List device measurements
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/devices/1/measurements" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/devices/1/measurements"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"device_id": 17,
"data": {
"unit": "cm",
"length": 49.35
},
"created_at": "2026-09-22T11:24:37.000000Z"
},
{
"id": 2,
"device_id": 18,
"data": {
"unit": "cm",
"length": 21.12
},
"created_at": "2026-09-22T11:24:37.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device measurements",
"code": "DEVICE_MEASUREMENTS:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICE_MEASUREMENTS:LIST:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create device measurement
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/devices/1/measurements" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"data\": {
\"length\": 25.4,
\"unit\": \"cm\"
}
}"
const url = new URL(
"http://localhost:8000/api/devices/1/measurements"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"data": {
"length": 25.4,
"unit": "cm"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"device_id": 19,
"data": {
"unit": "cm",
"length": 49.74
},
"created_at": "2026-09-22T11:24:37.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create device measurements",
"code": "DEVICE_MEASUREMENTS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICE_MEASUREMENTS:CREATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete device measurement
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/measurements/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/measurements/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Device measurement deleted",
"code": "DEVICE_MEASUREMENTS:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete device measurements",
"code": "DEVICE_MEASUREMENTS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Measurement not found):
{
"message": "Device measurement not found",
"code": "DEVICE_MEASUREMENTS:DELETE:MEASUREMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Device Models
API endpoints for device models management
Get device models list
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/devices/models?active=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/devices/models"
);
const params = {
"active": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 3,
"name": "Zeus hand v1",
"type": "leg",
"orientation": "left",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
},
{
"id": 4,
"name": "Zeus hand v1",
"type": "arm",
"orientation": "right",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list device models",
"code": "DEVICE_MODELS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create device model
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/devices/models" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Zeus hand v1\",
\"type\": \"hand\",
\"orientation\": \"right\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/devices/models"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Zeus hand v1",
"type": "hand",
"orientation": "right",
"active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 5,
"name": "Zeus hand v1",
"type": "leg",
"orientation": "right",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create device model",
"code": "DEVICE_MODELS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update device model
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/devices/models/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Zeus hand v1\",
\"type\": \"hand\",
\"orientation\": \"left\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/devices/models/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Zeus hand v1",
"type": "hand",
"orientation": "left",
"active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 6,
"name": "Zeus hand v1",
"type": "leg",
"orientation": "left",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device model",
"code": "DEVICE_MODELS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device model not found):
{
"message": "Device model not found",
"code": "DEVICE_MODELS:UPDATE:MODEL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Device Peripherals
API endpoints for device peripherals management
List device peripherals
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/devices/peripherals" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/devices/peripherals"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "veritatis",
"company": "Fahey, Paucek and Abbott",
"internal_id": "e26eb1a3-c2c8-3edb-8509-26aa752b0e7f",
"type": "magni",
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
},
{
"id": 2,
"name": "eum",
"company": "Watsica, Hauck and Douglas",
"internal_id": "254351b6-1c47-3375-b5c6-119a6bb87969",
"type": "fuga",
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device peripherals",
"code": "DEVICE_PERIPHERALS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create device peripheral
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/devices/peripherals" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Bluetooth Dongle\",
\"company\": \"Acme Corp\",
\"internal_id\": \"BT-DONGLE-001\",
\"type\": \"bluetooth_dongle\"
}"
const url = new URL(
"http://localhost:8000/api/devices/peripherals"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Bluetooth Dongle",
"company": "Acme Corp",
"internal_id": "BT-DONGLE-001",
"type": "bluetooth_dongle"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "dolores",
"company": "Kihn, Lehner and Larson",
"internal_id": "91de72ae-a98a-3a5c-b4e1-61bfffa9e828",
"type": "commodi",
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage device peripherals",
"code": "DEVICE_PERIPHERALS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update device peripheral
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/devices/peripherals/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Bluetooth Dongle\",
\"company\": \"Acme Corp\",
\"internal_id\": \"BT-DONGLE-001\",
\"type\": \"bluetooth_dongle\"
}"
const url = new URL(
"http://localhost:8000/api/devices/peripherals/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Bluetooth Dongle",
"company": "Acme Corp",
"internal_id": "BT-DONGLE-001",
"type": "bluetooth_dongle"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"name": "sed",
"company": "Casper PLC",
"internal_id": "b1a27300-2f64-387f-9ae8-cdbdc6f9bf83",
"type": "in",
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage device peripherals",
"code": "DEVICE_PERIPHERALS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Peripheral not found):
{
"message": "Device peripheral not found",
"code": "DEVICE_PERIPHERALS:UPDATE:PERIPHERAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete device peripheral
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/devices/peripherals/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/devices/peripherals/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Device peripheral deleted",
"code": "DEVICE_PERIPHERALS:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage device peripherals",
"code": "DEVICE_PERIPHERALS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Peripheral not found):
{
"message": "Device peripheral not found",
"code": "DEVICE_PERIPHERALS:DELETE:PERIPHERAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Devices
API endpoints for devices management
Check serial number or bluetooth ID
Public endpoint responding with status of given device serial number or bluetooth ID. If any of these numbers can be found in database, status will be true. Otherwise, status will be false (device does not exist).
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/check/S3R1AL-NUM83R" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"serial\"
}"
const url = new URL(
"http://localhost:8000/api/device/check/S3R1AL-NUM83R"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "serial"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"status": true
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get devices list
requires authentication
Possible extend options:
- model - device model details
- amputee - end-user assigned to device
- clinicians - list of clinicians assigned to the device
- firmwareVersion - device firmware version
- pcbVersion - PCB version
Example request:
curl --request GET \
--get "http://localhost:8000/api/devices?search=S3R1AL-NUM83R&active=-1&utee=1&clinician=1&model=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/devices"
);
const params = {
"search": "S3R1AL-NUM83R",
"active": "-1",
"amputee": "1",
"clinician": "1",
"model": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 5,
"serial": "eee6be9c-0bae-39de-8c1a-34c902ff7382",
"bluetooth_id": "0a8d4d72-208e-37a2-b2a2-8087a3f8cd5c",
"company_id": null,
"model_id": 7,
"amputee_id": 38,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z",
"first_config_change_at": null,
"model": {
"id": 7,
"name": "Zeus hand v1",
"type": "arm",
"orientation": "left",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
},
"amputee": {
"id": 38,
"mrn": "CSUCP4V71790076275",
"name": "Georgette Spinka",
"email": "1790076275ariel33@example.net",
"language": "en",
"phone": "1-520-932-6981",
"phone_country": "MF",
"phone_verified_at": null,
"address1": "28413 Hardy Mills",
"address2": "New Efrenville, AL 59900-7133",
"postal_code": "96488-4931",
"city": "Dickinson, Rowe and Thiel",
"country": "SE",
"clinic_name": "Melanyfurt",
"clinic_location": "629 Barton Wells\nMariettahaven, NJ 39971",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
},
{
"id": 6,
"serial": "44587be1-eb0f-3723-bf12-526eb3fa7595",
"bluetooth_id": "bcecaa18-2582-3312-a14f-fc6879c00e16",
"company_id": null,
"model_id": 8,
"amputee_id": 39,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z",
"first_config_change_at": null,
"model": {
"id": 8,
"name": "Zeus hand v1",
"type": "leg",
"orientation": "left",
"active": 1,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z"
},
"amputee": {
"id": 39,
"mrn": "TRH7P68K1790076275",
"name": "Easter Boyer",
"email": "1790076275ayla44@example.com",
"language": "en",
"phone": "+1-332-581-0570",
"phone_country": "CH",
"phone_verified_at": null,
"address1": "470 Wilderman Lake",
"address2": "Port Luz, CT 83827",
"postal_code": "29565-3186",
"city": "Mitchell, Waters and Bins",
"country": "HR",
"clinic_name": "Bayerchester",
"clinic_location": "4440 Alice Lodge Suite 730\nNaderbury, IN 29174",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:35.000000Z",
"updated_at": "2026-09-22T11:24:35.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list devices",
"code": "DEVICES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get device information
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 7,
"serial": "21b40915-3a17-35cf-b711-84f9ec8a08f1",
"bluetooth_id": "ca9a1318-9bf3-3191-b966-9ce3f989f0c6",
"company_id": null,
"model_id": 9,
"amputee_id": 40,
"clinician_id": null,
"firmware_version_id": 1,
"pcb_version_id": 1,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z",
"first_config_change_at": null,
"model": {
"id": 9,
"name": "Zeus hand v1",
"type": "leg",
"orientation": "left",
"active": 1,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z"
},
"amputee": {
"id": 40,
"mrn": "ACC8MVZ81790076276",
"name": "Reanna Wisoky",
"email": "1790076276meta.lehner@example.net",
"language": "en",
"phone": "(781) 946-7237",
"phone_country": "DZ",
"phone_verified_at": null,
"address1": "8313 Breitenberg Port",
"address2": "North Maiyaton, UT 80400",
"postal_code": "69255-0253",
"city": "Bruen, Waters and Predovic",
"country": "FR",
"clinic_name": "West Elvaside",
"clinic_location": "16727 Schowalter Harbors Apt. 839\nJohnsbury, RI 09614",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"pcb_version": {
"id": 1,
"name": "1.62.54",
"hardware_id": "",
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z"
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device data",
"code": "DEVICES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:GET:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
Create new device
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"serial\": \"S3R1AL-NUM83R\",
\"bluetooth_id\": \"BL0123456789\",
\"model_id\": 1,
\"amputee_id\": 1,
\"clinicians\": [
2
],
\"peripherals\": [
1
],
\"firmware_version_id\": 1,
\"pcb_version_id\": 1,
\"reverse_magnets\": false,
\"is_electrode\": false,
\"active\": true,
\"last_activity_at\": \"2022-08-15 12:00:00\",
\"first_connected_at\": \"2022-08-15 12:00:00\",
\"measurements\": \"{\\\"length\\\": 25.4, \\\"unit\\\": \\\"cm\\\"}\"
}"
const url = new URL(
"http://localhost:8000/api/device"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"serial": "S3R1AL-NUM83R",
"bluetooth_id": "BL0123456789",
"model_id": 1,
"amputee_id": 1,
"clinicians": [
2
],
"peripherals": [
1
],
"firmware_version_id": 1,
"pcb_version_id": 1,
"reverse_magnets": false,
"is_electrode": false,
"active": true,
"last_activity_at": "2022-08-15 12:00:00",
"first_connected_at": "2022-08-15 12:00:00",
"measurements": "{\"length\": 25.4, \"unit\": \"cm\"}"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 8,
"serial": "318ea7e7-3c67-3f34-a9de-c2dff9a04181",
"bluetooth_id": "89ddef5e-41dd-3342-ab1b-618095f77352",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z",
"first_config_change_at": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create device",
"code": "DEVICES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Firmware has no schema):
{
"message": "Cannot create: firmware has no schema",
"code": "DEVICES:CREATE:NO_FIRMWARE_SCHEMA"
}
Example response (500, Server error):
{
"message": "Server error: device not created",
"code": "DEVICES:CREATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
Update device
requires authentication
Amputee of device can update only these fields:
serial, bluetooth_id, firmware_version_id, pcb_version_id
Example request:
curl --request PUT \
"http://localhost:8000/api/device/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"serial\": \"S3R1AL-NUM83R\",
\"bluetooth_id\": \"BL0123456789\",
\"model_id\": 1,
\"amputee_id\": 1,
\"clinicians\": [
2
],
\"peripherals\": [
1
],
\"firmware_version_id\": 1,
\"pcb_version_id\": 1,
\"reverse_magnets\": false,
\"is_electrode\": false,
\"active\": true,
\"last_activity_at\": \"2022-08-15 12:00:00\",
\"first_connected_at\": \"2022-08-15 12:00:00\",
\"measurements\": \"{\\\"length\\\": 25.4, \\\"unit\\\": \\\"cm\\\"}\"
}"
const url = new URL(
"http://localhost:8000/api/device/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"serial": "S3R1AL-NUM83R",
"bluetooth_id": "BL0123456789",
"model_id": 1,
"amputee_id": 1,
"clinicians": [
2
],
"peripherals": [
1
],
"firmware_version_id": 1,
"pcb_version_id": 1,
"reverse_magnets": false,
"is_electrode": false,
"active": true,
"last_activity_at": "2022-08-15 12:00:00",
"first_connected_at": "2022-08-15 12:00:00",
"measurements": "{\"length\": 25.4, \"unit\": \"cm\"}"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 9,
"serial": "782a73ae-c611-31ea-8473-5cc227e0fd01",
"bluetooth_id": "f934071b-ffbb-3043-a77a-3307f1214ea1",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:36.000000Z",
"updated_at": "2026-09-22T11:24:36.000000Z",
"first_config_change_at": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device",
"code": "DEVICES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Firmware has no schema):
{
"message": "Cannot update: firmware has no schema",
"code": "DEVICES:UPDATE:NO_FIRMWARE_SCHEMA"
}
Example response (403):
{
"message": "Cannot update: no clinicians left for patient relation",
"code": "DEVICES:UPDATE:NO_CLINICIANS"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:UPDATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
Delete device
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/device/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Device deleted",
"code": "DEVICES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete device",
"code": "DEVICES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:DELETE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get device hashes
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/hash" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/hash"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"hash_global": "123456789012345",
"hash_common_settings": "123456789012345",
"hash_common_grips": "123456789012345",
"hash_mode1": "123456789012345",
"hash_mode2": "123456789012345",
"hash_mode3": "123456789012345"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access device hashes",
"code": "DEVICES:GET_HASHES:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:GET_HASHES:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update device hashes
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/hash" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"hash_global\": \"123456789012345\",
\"hash_common_settings\": \"123456789012345\",
\"hash_common_grips\": \"123456789012345\",
\"hash_mode1\": \"123456789012345\",
\"hash_mode2\": \"123456789012345\",
\"hash_mode3\": \"123456789012345\"
}"
const url = new URL(
"http://localhost:8000/api/device/1/hash"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"hash_global": "123456789012345",
"hash_common_settings": "123456789012345",
"hash_common_grips": "123456789012345",
"hash_mode1": "123456789012345",
"hash_mode2": "123456789012345",
"hash_mode3": "123456789012345"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"hash_global": "123456789012345",
"hash_common_settings": "123456789012345",
"hash_common_grips": "123456789012345",
"hash_mode1": "123456789012345",
"hash_mode2": "123456789012345",
"hash_mode3": "123456789012345"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access device hashes",
"code": "DEVICES:SET_HASHES:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:SET_HASHES:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Detach device
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/detach" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/detach"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Device detached",
"code": "DEVICES:DETACH:DETACHED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to detach device",
"code": "DEVICES:DETACH:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:DETACH:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Add device
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/add/S3R1AL-NUM83R" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/add/S3R1AL-NUM83R"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
{
"id": 10,
"serial": "f71b2e45-785d-3433-8211-4eb0dfd15e34",
"bluetooth_id": "ff1827cc-226f-3357-9ac1-bd2a81d4fd21",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z",
"first_config_change_at": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to assign devices with code",
"code": "DEVICES:ASSIGN:INSUFFICIENT_PERMISSION"
}
Example response (403, User reached the temporary limit of attached devices):
{
"message": "Reached the limit of assigned devices",
"code": "DEVICES:ASSIGN:LIMIT_REACHED"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:ASSIGN:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
Connect device
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/connect/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/connect/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Device connected",
"code": "DEVICES:CONNECT:CONNECTED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device data",
"code": "DEVICES:CONNECT:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:CONNECT:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Disconnect device
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/disconnect/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/disconnect/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Device disconnected",
"code": "DEVICES:DISCONNECT:DISCONNECTED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view device data",
"code": "DEVICES:DISCONNECT:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:DISCONNECT:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Join devices
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/join/1/2" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"force\": false,
\"patient\": 1
}"
const url = new URL(
"http://localhost:8000/api/device/join/1/2"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"force": false,
"patient": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 11,
"serial": "5bae0bbe-e9cc-3095-85ff-506af66a5844",
"bluetooth_id": "4b49277e-3694-32e9-b888-fd32086fe952",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z",
"first_config_change_at": null,
"joined_devices": [
{
"id": 12,
"serial": "724e82d1-e61e-368c-9c5e-50ca3d640c40",
"bluetooth_id": "c41c02fa-ecd7-315b-9ac0-18be580080ca",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z",
"first_config_change_at": null,
"pivot": {
"electrode_id": 11,
"device_id": 12,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
}
],
"joined_electrodes": [
{
"id": 13,
"serial": "533bceb6-fc65-395d-a6fd-81b200f5bfe2",
"bluetooth_id": "75d70761-6a87-344b-97e7-2e68b2640d38",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z",
"first_config_change_at": null,
"pivot": {
"device_id": 11,
"electrode_id": 13,
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to join devices",
"code": "DEVICES:JOIN:INSUFFICIENT_PERMISSION"
}
Example response (403, Device 2 has a patient assigned):
{
"message": "Device 2 has a patient assigned",
"code": "DEVICES:JOIN:DEVICE2_HAS_PATIENT"
}
Example response (403, Device already has an electrode joined):
{
"message": "Device already has an electrode joined",
"code": "DEVICES:JOIN:ALREADY_JOINED"
}
Example response (403, Server error):
{
"message": "Server error",
"code": "DEVICES:JOIN:SERVER_ERROR"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:JOIN:DEVICE_NOT_FOUND"
}
Example response (404, Device 1 cannot be an electrode):
{
"message": "Device 1 cannot be an electrode",
"code": "DEVICES:JOIN:INCORRECT_DEVICE1_TYPE"
}
Example response (404, Device 2 must be an electrode):
{
"message": "Device 1 must be an electrode",
"code": "DEVICES:JOIN:INCORRECT_DEVICE2_TYPE"
}
Example response (404, Both devices have no patient assigned):
{
"message": "Both devices have no patient assigned",
"code": "DEVICES:JOIN:NO_PATIENT"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
Detach joined devices
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/unjoin/1/2" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/unjoin/1/2"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Devices unjoined",
"code": "DEVICES:UNJOIN:UNJOINED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to join devices",
"code": "DEVICES:UNJOIN:INSUFFICIENT_PERMISSION"
}
Example response (403, OK):
{
"message": "Devices are not joined",
"code": "DEVICES:UNJOIN:NOT_JOINED"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:UNJOIN:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create demo patient
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/dummy-patient" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/dummy-patient"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201, OK):
{
"email": "SERIAL@gmail.com",
"password": "Demo@123"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create dummy patient",
"code": "DEVICES:DUMMY_PATIENT:INSUFFICIENT_PERMISSION"
}
Example response (403, Device already has a patient):
{
"message": "Device already has a patient",
"code": "DEVICES:DUMMY_PATIENT:PATIENT_EXISTS"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "DEVICES:DUMMY_PATIENT:DEVICE_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: dummy patient not created",
"code": "DEVICES:DUMMY_PATIENT:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get device internal note
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/17/internal-note" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/17/internal-note"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"device_id": 20,
"note": "Delectus maxime eum mollitia et at est vero. Voluptates quibusdam consectetur aliquam occaecati ea. Quaerat suscipit animi ab iste suscipit.",
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access internal notes",
"code": "INTERNAL_NOTE:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "INTERNAL_NOTE:GET:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update device internal note
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/device/1/internal-note" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"note\": \"Device returned from clinic for inspection.\"
}"
const url = new URL(
"http://localhost:8000/api/device/1/internal-note"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"note": "Device returned from clinic for inspection."
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 2,
"device_id": 21,
"note": "Quibusdam ut culpa reiciendis saepe. Sed saepe consectetur porro architecto sed corrupti. A qui unde dicta consequatur distinctio quia sunt at.",
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access internal notes",
"code": "INTERNAL_NOTE:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "INTERNAL_NOTE:UPDATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Documents
API endpoints for documents management
List documents
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/documents?type=web" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents"
);
const params = {
"type": "web",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "Lifeguard",
"type": "web",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
},
{
"id": 2,
"name": "Poet OR Lyricist",
"type": "web",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Document ID.
name
string
Document name.
type
string
Document target platform.
Must be one of:webmobile
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
versions
object[]
Document versions.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create document
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/documents" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Privacy Policy\",
\"type\": \"web\"
}"
const url = new URL(
"http://localhost:8000/api/documents"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Privacy Policy",
"type": "web"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "Manufacturing Sales Representative",
"type": "web",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Document ID.
name
string
Document name.
type
string
Document target platform.
Must be one of:webmobile
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
versions
object[]
Document versions.
Delete document
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/documents/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Document deleted",
"code": "DOCUMENTS:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, Document has existing versions):
{
"message": "Cannot delete: document has existing versions (1)",
"code": "DOCUMENTS:DELETE:HAS_VERSIONS"
}
Example response (404, Document not found):
{
"message": "Document not found",
"code": "DOCUMENTS:DELETE:DOCUMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List document versions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/documents/1/versions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents/1/versions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"document_id": null,
"index": 40,
"file": "http://www.miller.net/distinctio-atque-nesciunt-eius-sed.html",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
},
{
"id": 2,
"document_id": null,
"index": 74,
"file": "http://www.ebert.com/",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:LIST_VERSIONS:INSUFFICIENT_PERMISSION"
}
Example response (404, Document not found):
{
"message": "Document not found",
"code": "DOCUMENTS:LIST_VERSIONS:DOCUMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Document version ID.
document_id
integer
Associated document ID.
index
integer
Version index number.
file
string
File path or URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
document
object
Parent document.
Create document version
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/documents/1/versions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"file\": \"https:\\/\\/www.aetherbiomedical.com\\/privacy-policy\"
}"
const url = new URL(
"http://localhost:8000/api/documents/1/versions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"file": "https:\/\/www.aetherbiomedical.com\/privacy-policy"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"document_id": null,
"index": 7999794,
"file": "http://www.lehner.info/",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:CREATE_VERSION:INSUFFICIENT_PERMISSION"
}
Example response (404, Document not found):
{
"message": "Document not found",
"code": "DOCUMENTS:CREATE_VERSION:DOCUMENT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Document version ID.
document_id
integer
Associated document ID.
index
integer
Version index number.
file
string
File path or URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
document
object
Parent document.
Delete document version
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/documents/1/versions/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents/1/versions/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Document version deleted",
"code": "DOCUMENTS:DELETE_VERSION:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage documents",
"code": "DOCUMENTS:DELETE_VERSION:INSUFFICIENT_PERMISSION"
}
Example response (404, Document not found):
{
"message": "Document not found",
"code": "DOCUMENTS:DELETE_VERSION:DOCUMENT_NOT_FOUND"
}
Example response (404, Document version not found):
{
"message": "Document version not found",
"code": "DOCUMENTS:DELETE_VERSION:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get documents status
requires authentication
Any document on the list has to be accepted. Use POST /documents/accept endpoint to mark them as accepted once user agrees to that.
Empty list means that user is up-to-date with all required documents and nothing has to be accepted.
Example request:
curl --request GET \
--get "http://localhost:8000/api/documents/status?type=web" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents/status"
);
const params = {
"type": "web",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"documents": []
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view documents status",
"code": "DOCUMENTS:STATUS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Accept documents
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/documents/accept" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"documents\": [
1
]
}"
const url = new URL(
"http://localhost:8000/api/documents/accept"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"documents": [
1
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"message": "Accepted 1 document(s)",
"code": "DOCUMENTS:ACCEPT:ACCEPTED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update documents status",
"code": "DOCUMENTS:ACCEPT:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Accept Terms of Service for patients
requires authentication
This endpoint does not save any information to the database. Its purpose is to make sure the patient will be saved in the HubSpot.
Example request:
curl --request POST \
"http://localhost:8000/api/documents/accept/tos" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/documents/accept/tos"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Patients' \"Terms of Service\" accepted",
"code": "DOCUMENTS:ACCEPT_PATIENT_TOS:ACCEPTED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to accept patients' \"Terms of Service\"",
"code": "DOCUMENTS:ACCEPT_PATIENT_TOS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Feedback
Endpoints related to feedback collecting
Check feedback token
Example request:
curl --request POST \
"http://localhost:8000/api/feedback/4KJ2YLM0MA64Y6D6FUY2OFY690IICO1OJ2DHR6T68IZNI528H3SKUFJMY0C5DHOA/check" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/4KJ2YLM0MA64Y6D6FUY2OFY690IICO1OJ2DHR6T68IZNI528H3SKUFJMY0C5DHOA/check"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"valid": true
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send feedback with token
Example request:
curl --request POST \
"http://localhost:8000/api/feedback/4KJ2YLM0MA64Y6D6FUY2OFY690IICO1OJ2DHR6T68IZNI528H3SKUFJMY0C5DHOA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"contextual\",
\"trigger\": \"remote_session\",
\"rate\": 5,
\"description\": \"That was amazing!\",
\"skipped\": false,
\"training_day_id\": 1
}"
const url = new URL(
"http://localhost:8000/api/feedback/4KJ2YLM0MA64Y6D6FUY2OFY690IICO1OJ2DHR6T68IZNI528H3SKUFJMY0C5DHOA"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "contextual",
"trigger": "remote_session",
"rate": 5,
"description": "That was amazing!",
"skipped": false,
"training_day_id": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"user_id": 6,
"type": "periodic",
"trigger": "local_session",
"platform": "web",
"rate": 1,
"description": "Fugit optio tempore harum.",
"skipped": 1,
"training_day_id": null,
"created_at": "2026-09-22T11:24:20.000000Z",
"updated_at": "2026-09-22T11:24:20.000000Z"
}
Example response (403, Invalid token):
{
"message": "Invalid token",
"code": "FEEDBACK:SEND_WITH_TOKEN:INVALID_TOKEN"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Feedback ID.
user_id
integer
User who submitted the feedback.
type
string
Feedback type.
trigger
string
What triggered the feedback.
platform
string
Platform the feedback was submitted from.
rate
integer
Feedback rating.
description
string
Feedback description.
skipped
boolean
Whether the feedback was skipped.
training_day_id
integer
Associated training day ID.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Get feedback status
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"remote_session": true,
"firmware_update": true,
"local_session": true,
"async_session": true,
"patient_create": false,
"clinician_invite": true
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to check feedback status",
"code": "FEEDBACK:STATUS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Send feedback
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/feedback" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"contextual\",
\"trigger\": \"remote_session\",
\"platform\": \"web\",
\"rate\": 5,
\"description\": \"That was amazing!\",
\"skipped\": false,
\"training_day_id\": 1
}"
const url = new URL(
"http://localhost:8000/api/feedback"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "contextual",
"trigger": "remote_session",
"platform": "web",
"rate": 5,
"description": "That was amazing!",
"skipped": false,
"training_day_id": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 2,
"user_id": 311,
"type": "periodic",
"trigger": "remote_session",
"platform": "web",
"rate": 4,
"description": "Minus dolore sit libero.",
"skipped": 0,
"training_day_id": null,
"created_at": "2026-09-22T11:26:59.000000Z",
"updated_at": "2026-09-22T11:26:59.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to send feedback",
"code": "FEEDBACK:SEND:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Feedback ID.
user_id
integer
User who submitted the feedback.
type
string
Feedback type.
trigger
string
What triggered the feedback.
platform
string
Platform the feedback was submitted from.
rate
integer
Feedback rating.
description
string
Feedback description.
skipped
boolean
Whether the feedback was skipped.
training_day_id
integer
Associated training day ID.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Schedule feedback notification
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/feedback/schedule" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"trigger\": \"remote_session\"
}"
const url = new URL(
"http://localhost:8000/api/feedback/schedule"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"trigger": "remote_session"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"scheduled_at": "2026-04-13 12:00:00"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to schedule feedback notification",
"code": "FEEDBACK:SCHEDULE:INSUFFICIENT_PERMISSION"
}
Example response (403, Feedback with this trigger was already scheduled today):
{
"message": "Feedback with this trigger was already scheduled today",
"code": "FEEDBACK:SCHEDULE:ALREADY_SCHEDULED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List feedback
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (201):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 25,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 3,
"user_id": 312,
"type": "on_demand",
"trigger": "async_session",
"platform": "mobile",
"rate": 4,
"description": "Rerum sed odit consequatur id.",
"skipped": 1,
"training_day_id": null,
"created_at": "2026-09-22T11:27:00.000000Z",
"updated_at": "2026-09-22T11:27:00.000000Z"
},
{
"id": 4,
"user_id": 313,
"type": "on_demand",
"trigger": "clinician_invite",
"platform": "mobile",
"rate": 1,
"description": "In dolor repellendus libero nisi saepe sed consequatur.",
"skipped": 1,
"training_day_id": null,
"created_at": "2026-09-22T11:27:00.000000Z",
"updated_at": "2026-09-22T11:27:00.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list feedback",
"code": "FEEDBACK:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Feedback ID.
user_id
integer
User who submitted the feedback.
type
string
Feedback type.
trigger
string
What triggered the feedback.
platform
string
Platform the feedback was submitted from.
rate
integer
Feedback rating.
description
string
Feedback description.
skipped
boolean
Whether the feedback was skipped.
training_day_id
integer
Associated training day ID.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Export feedback to CSV
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback/csv" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/csv"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, CSV file):
{
"file": "https://staging-us-east-2-aether-biomedical-s3-us-bucket.s3.us-east-2.amazonaws.com/feedback/feedback-1759228216.csv",
"expires": "2025-09-30 10:40:00"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to export feedback",
"code": "FEEDBACK:EXPORT_CSV:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get feedback cooldowns
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback/cooldowns" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/cooldowns"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"remote_session": 1,
"local_session": 1,
"async_session": 1,
"patient_create": 1,
"clinician_invite": 1,
"firmware_update": 1,
"new_config": 1,
"grip_change": 1
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage feedback cooldowns",
"code": "FEEDBACK:GET_COOLDOWNS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update feedback cooldowns
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/feedback/cooldowns" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"remote_session\": 1,
\"local_session\": 1,
\"async_session\": 1,
\"patient_create\": 1,
\"clinician_invite\": 1,
\"firmware_update\": 1,
\"new_config\": 1,
\"grip_change\": 1
}"
const url = new URL(
"http://localhost:8000/api/feedback/cooldowns"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"remote_session": 1,
"local_session": 1,
"async_session": 1,
"patient_create": 1,
"clinician_invite": 1,
"firmware_update": 1,
"new_config": 1,
"grip_change": 1
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"remote_session": 1,
"local_session": 1,
"async_session": 1,
"patient_create": 1,
"clinician_invite": 1,
"firmware_update": 1,
"new_config": 1,
"grip_change": 1
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage feedback cooldowns",
"code": "FEEDBACK:UPDATE_COOLDOWNS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get feedback enabled
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback/enabled" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/enabled"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"remote_session": true,
"local_session": true,
"async_session": true,
"patient_create": true,
"clinician_invite": true,
"firmware_update": true,
"new_config": true,
"grip_change": true
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage feedback cooldowns",
"code": "FEEDBACK:GET_ENABLED:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set feedback enabled
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/feedback/enabled" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"remote_session\": false,
\"local_session\": false,
\"async_session\": false,
\"patient_create\": false,
\"clinician_invite\": false,
\"firmware_update\": false,
\"new_config\": false,
\"grip_change\": false
}"
const url = new URL(
"http://localhost:8000/api/feedback/enabled"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"remote_session": false,
"local_session": false,
"async_session": false,
"patient_create": false,
"clinician_invite": false,
"firmware_update": false,
"new_config": false,
"grip_change": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"remote_session": true,
"local_session": true,
"async_session": true,
"patient_create": true,
"clinician_invite": true,
"firmware_update": true,
"new_config": true,
"grip_change": true
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage feedback cooldowns",
"code": "FEEDBACK:SET_ENABLED:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Feedback statistics
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/feedback/statistics" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/feedback/statistics"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"submitted": 100,
"skipped": 150,
"total": 250,
"average_rating": 4.76
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view feedback statistics",
"code": "FEEDBACK:STATISTICS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Finger Calibrations
API endpoints for managing finger calibration results
Get finger calibration
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/device/1/finger-calibration" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/device/1/finger-calibration"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"device_id": 14,
"result": "aliquam",
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
},
{
"id": 2,
"device_id": 15,
"result": "exercitationem",
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view finger calibration data",
"code": "FINGER_CALIBRATION:VIEW:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "FINGER_CALIBRATION:VIEW:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Store finger calibration
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/finger-calibration" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"result\": \"test\"
}"
const url = new URL(
"http://localhost:8000/api/device/1/finger-calibration"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"result": "test"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"device_id": 16,
"result": "accusantium",
"created_at": "2026-09-22T11:24:37.000000Z",
"updated_at": "2026-09-22T11:24:37.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create finger calibration",
"code": "FINGER_CALIBRATION:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "FINGER_CALIBRATION:CREATE:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
GeoData
API endpoints for geodata
Get supported timezones list
Example request:
curl --request GET \
--get "http://localhost:8000/api/timezones" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/timezones"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
[
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"Africa/Algiers",
"Africa/Asmara",
"Africa/Bamako",
"Africa/Bangui",
"Africa/Banjul",
"Africa/Bissau",
"Africa/Blantyre",
"Africa/Brazzaville",
"Africa/Bujumbura",
"Africa/Cairo",
"Africa/Casablanca",
"Africa/Ceuta",
"Africa/Conakry",
"Africa/Dakar",
"Africa/Dar_es_Salaam",
"Africa/Djibouti",
"Africa/Douala",
"Africa/El_Aaiun",
"Africa/Freetown",
"Africa/Gaborone",
"Africa/Harare",
"Africa/Johannesburg",
"Africa/Juba",
"Africa/Kampala",
"Africa/Khartoum",
"Africa/Kigali",
"Africa/Kinshasa",
"Africa/Lagos",
"Africa/Libreville",
"Africa/Lome",
"Africa/Luanda",
"Africa/Lubumbashi",
"Africa/Lusaka",
"Africa/Malabo",
"Africa/Maputo",
"Africa/Maseru",
"Africa/Mbabane",
"Africa/Mogadishu",
"Africa/Monrovia",
"Africa/Nairobi",
"Africa/Ndjamena",
"Africa/Niamey",
"Africa/Nouakchott",
"Africa/Ouagadougou",
"Africa/Porto-Novo",
"Africa/Sao_Tome",
"Africa/Tripoli",
"Africa/Tunis",
"Africa/Windhoek",
"America/Adak",
"America/Anchorage",
"America/Anguilla",
"America/Antigua",
"America/Araguaina",
"America/Argentina/Buenos_Aires",
"America/Argentina/Catamarca",
"America/Argentina/Cordoba",
"America/Argentina/Jujuy",
"America/Argentina/La_Rioja",
"America/Argentina/Mendoza",
"America/Argentina/Rio_Gallegos",
"America/Argentina/Salta",
"America/Argentina/San_Juan",
"America/Argentina/San_Luis",
"America/Argentina/Tucuman",
"America/Argentina/Ushuaia",
"America/Aruba",
"America/Asuncion",
"America/Atikokan",
"America/Bahia",
"America/Bahia_Banderas",
"America/Barbados",
"America/Belem",
"America/Belize",
"America/Blanc-Sablon",
"America/Boa_Vista",
"America/Bogota",
"America/Boise",
"America/Cambridge_Bay",
"America/Campo_Grande",
"America/Cancun",
"America/Caracas",
"America/Cayenne",
"America/Cayman",
"America/Chicago",
"America/Chihuahua",
"America/Costa_Rica",
"America/Creston",
"America/Cuiaba",
"America/Curacao",
"America/Danmarkshavn",
"America/Dawson",
"America/Dawson_Creek",
"America/Denver",
"America/Detroit",
"America/Dominica",
"America/Edmonton",
"America/Eirunepe",
"America/El_Salvador",
"America/Fort_Nelson",
"America/Fortaleza",
"America/Glace_Bay",
"America/Goose_Bay",
"America/Grand_Turk",
"America/Grenada",
"America/Guadeloupe",
"America/Guatemala",
"America/Guayaquil",
"America/Guyana",
"America/Halifax",
"America/Havana",
"America/Hermosillo",
"America/Indiana/Indianapolis",
"America/Indiana/Knox",
"America/Indiana/Marengo",
"America/Indiana/Petersburg",
"America/Indiana/Tell_City",
"America/Indiana/Vevay",
"America/Indiana/Vincennes",
"America/Indiana/Winamac",
"America/Inuvik",
"America/Iqaluit",
"America/Jamaica",
"America/Juneau",
"America/Kentucky/Louisville",
"America/Kentucky/Monticello",
"America/Kralendijk",
"America/La_Paz",
"America/Lima",
"America/Los_Angeles",
"America/Lower_Princes",
"America/Maceio",
"America/Managua",
"America/Manaus",
"America/Marigot",
"America/Martinique",
"America/Matamoros",
"America/Mazatlan",
"America/Menominee",
"America/Merida",
"America/Metlakatla",
"America/Mexico_City",
"America/Miquelon",
"America/Moncton",
"America/Monterrey",
"America/Montevideo",
"America/Montserrat",
"America/Nassau",
"America/New_York",
"America/Nipigon",
"America/Nome",
"America/Noronha",
"America/North_Dakota/Beulah",
"America/North_Dakota/Center",
"America/North_Dakota/New_Salem",
"America/Nuuk",
"America/Ojinaga",
"America/Panama",
"America/Pangnirtung",
"America/Paramaribo",
"America/Phoenix",
"America/Port-au-Prince",
"America/Port_of_Spain",
"America/Porto_Velho",
"America/Puerto_Rico",
"America/Punta_Arenas",
"America/Rainy_River",
"America/Rankin_Inlet",
"America/Recife",
"America/Regina",
"America/Resolute",
"America/Rio_Branco",
"America/Santarem",
"America/Santiago",
"America/Santo_Domingo",
"America/Sao_Paulo",
"America/Scoresbysund",
"America/Sitka",
"America/St_Barthelemy",
"America/St_Johns",
"America/St_Kitts",
"America/St_Lucia",
"America/St_Thomas",
"America/St_Vincent",
"America/Swift_Current",
"America/Tegucigalpa",
"America/Thule",
"America/Thunder_Bay",
"America/Tijuana",
"America/Toronto",
"America/Tortola",
"America/Vancouver",
"America/Whitehorse",
"America/Winnipeg",
"America/Yakutat",
"America/Yellowknife",
"Antarctica/Casey",
"Antarctica/Davis",
"Antarctica/DumontDUrville",
"Antarctica/Macquarie",
"Antarctica/Mawson",
"Antarctica/McMurdo",
"Antarctica/Palmer",
"Antarctica/Rothera",
"Antarctica/Syowa",
"Antarctica/Troll",
"Antarctica/Vostok",
"Arctic/Longyearbyen",
"Asia/Aden",
"Asia/Almaty",
"Asia/Amman",
"Asia/Anadyr",
"Asia/Aqtau",
"Asia/Aqtobe",
"Asia/Ashgabat",
"Asia/Atyrau",
"Asia/Baghdad",
"Asia/Bahrain",
"Asia/Baku",
"Asia/Bangkok",
"Asia/Barnaul",
"Asia/Beirut",
"Asia/Bishkek",
"Asia/Brunei",
"Asia/Chita",
"Asia/Choibalsan",
"Asia/Colombo",
"Asia/Damascus",
"Asia/Dhaka",
"Asia/Dili",
"Asia/Dubai",
"Asia/Dushanbe",
"Asia/Famagusta",
"Asia/Gaza",
"Asia/Hebron",
"Asia/Ho_Chi_Minh",
"Asia/Hong_Kong",
"Asia/Hovd",
"Asia/Irkutsk",
"Asia/Jakarta",
"Asia/Jayapura",
"Asia/Jerusalem",
"Asia/Kabul",
"Asia/Kamchatka",
"Asia/Karachi",
"Asia/Kathmandu",
"Asia/Khandyga",
"Asia/Kolkata",
"Asia/Krasnoyarsk",
"Asia/Kuala_Lumpur",
"Asia/Kuching",
"Asia/Kuwait",
"Asia/Macau",
"Asia/Magadan",
"Asia/Makassar",
"Asia/Manila",
"Asia/Muscat",
"Asia/Nicosia",
"Asia/Novokuznetsk",
"Asia/Novosibirsk",
"Asia/Omsk",
"Asia/Oral",
"Asia/Phnom_Penh",
"Asia/Pontianak",
"Asia/Pyongyang",
"Asia/Qatar",
"Asia/Qostanay",
"Asia/Qyzylorda",
"Asia/Riyadh",
"Asia/Sakhalin",
"Asia/Samarkand",
"Asia/Seoul",
"Asia/Shanghai",
"Asia/Singapore",
"Asia/Srednekolymsk",
"Asia/Taipei",
"Asia/Tashkent",
"Asia/Tbilisi",
"Asia/Tehran",
"Asia/Thimphu",
"Asia/Tokyo",
"Asia/Tomsk",
"Asia/Ulaanbaatar",
"Asia/Urumqi",
"Asia/Ust-Nera",
"Asia/Vientiane",
"Asia/Vladivostok",
"Asia/Yakutsk",
"Asia/Yangon",
"Asia/Yekaterinburg",
"Asia/Yerevan",
"Atlantic/Azores",
"Atlantic/Bermuda",
"Atlantic/Canary",
"Atlantic/Cape_Verde",
"Atlantic/Faroe",
"Atlantic/Madeira",
"Atlantic/Reykjavik",
"Atlantic/South_Georgia",
"Atlantic/St_Helena",
"Atlantic/Stanley",
"Australia/Adelaide",
"Australia/Brisbane",
"Australia/Broken_Hill",
"Australia/Darwin",
"Australia/Eucla",
"Australia/Hobart",
"Australia/Lindeman",
"Australia/Lord_Howe",
"Australia/Melbourne",
"Australia/Perth",
"Australia/Sydney",
"Europe/Amsterdam",
"Europe/Andorra",
"Europe/Astrakhan",
"Europe/Athens",
"Europe/Belgrade",
"Europe/Berlin",
"Europe/Bratislava",
"Europe/Brussels",
"Europe/Bucharest",
"Europe/Budapest",
"Europe/Busingen",
"Europe/Chisinau",
"Europe/Copenhagen",
"Europe/Dublin",
"Europe/Gibraltar",
"Europe/Guernsey",
"Europe/Helsinki",
"Europe/Isle_of_Man",
"Europe/Istanbul",
"Europe/Jersey",
"Europe/Kaliningrad",
"Europe/Kiev",
"Europe/Kirov",
"Europe/Lisbon",
"Europe/Ljubljana",
"Europe/London",
"Europe/Luxembourg",
"Europe/Madrid",
"Europe/Malta",
"Europe/Mariehamn",
"Europe/Minsk",
"Europe/Monaco",
"Europe/Moscow",
"Europe/Oslo",
"Europe/Paris",
"Europe/Podgorica",
"Europe/Prague",
"Europe/Riga",
"Europe/Rome",
"Europe/Samara",
"Europe/San_Marino",
"Europe/Sarajevo",
"Europe/Saratov",
"Europe/Simferopol",
"Europe/Skopje",
"Europe/Sofia",
"Europe/Stockholm",
"Europe/Tallinn",
"Europe/Tirane",
"Europe/Ulyanovsk",
"Europe/Uzhgorod",
"Europe/Vaduz",
"Europe/Vatican",
"Europe/Vienna",
"Europe/Vilnius",
"Europe/Volgograd",
"Europe/Warsaw",
"Europe/Zagreb",
"Europe/Zaporozhye",
"Europe/Zurich",
"Indian/Antananarivo",
"Indian/Chagos",
"Indian/Christmas",
"Indian/Cocos",
"Indian/Comoro",
"Indian/Kerguelen",
"Indian/Mahe",
"Indian/Maldives",
"Indian/Mauritius",
"Indian/Mayotte",
"Indian/Reunion",
"Pacific/Apia",
"Pacific/Auckland",
"Pacific/Bougainville",
"Pacific/Chatham",
"Pacific/Chuuk",
"Pacific/Easter",
"Pacific/Efate",
"Pacific/Fakaofo",
"Pacific/Fiji",
"Pacific/Funafuti",
"Pacific/Galapagos",
"Pacific/Gambier",
"Pacific/Guadalcanal",
"Pacific/Guam",
"Pacific/Honolulu",
"Pacific/Kanton",
"Pacific/Kiritimati",
"Pacific/Kosrae",
"Pacific/Kwajalein",
"Pacific/Majuro",
"Pacific/Marquesas",
"Pacific/Midway",
"Pacific/Nauru",
"Pacific/Niue",
"Pacific/Norfolk",
"Pacific/Noumea",
"Pacific/Pago_Pago",
"Pacific/Palau",
"Pacific/Pitcairn",
"Pacific/Pohnpei",
"Pacific/Port_Moresby",
"Pacific/Rarotonga",
"Pacific/Saipan",
"Pacific/Tahiti",
"Pacific/Tarawa",
"Pacific/Tongatapu",
"Pacific/Wake",
"Pacific/Wallis",
"UTC"
]
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Goals
API endpoints for goals
The goals module consists of:
- exercises - predefined actions which should be performed by patient. Exercises can be managed only by SuperAdmin,
- goals - objectives defined for each patient which could consists of exercises, grips and grip switches,
- goal conditions - parts of the goal, single condition of type exercise, grips goal or switches goal.
List grips
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/grips?model=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/grips"
);
const params = {
"model": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"number": 6014,
"name": "laudantium grip",
"description": null,
"opposed": 0,
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
},
{
"id": 2,
"number": 9158,
"name": "qui grip",
"description": null,
"opposed": 0,
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view grips",
"code": "GOALS:LIST_GRIPS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Grip ID.
number
integer
Grip number identifier.
name
string
Grip name.
description
string
Grip description.
opposed
boolean
Whether the grip is opposed.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
List exercises
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/exercises" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/exercises"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "exercises.Macejkovic Crossroad",
"description": "exercises.Quo deserunt hic modi dolores.",
"icon": "😝",
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
},
{
"id": 2,
"name": "exercises.Blair Dam",
"description": "exercises.Quasi reprehenderit velit consectetur ratione sit enim sit magni.",
"icon": "😉",
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view exercises",
"code": "GOALS:LIST_EXERCISES:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Exercise ID.
name
string
Exercise name.
description
string
Exercise description.
icon
string
Exercise icon identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create exercise
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/exercises" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Water plants\",
\"description\": \"Use Tripod Close Grip and water your plants\",
\"icon\": \"🪴\"
}"
const url = new URL(
"http://localhost:8000/api/exercises"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Water plants",
"description": "Use Tripod Close Grip and water your plants",
"icon": "🪴"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "exercises.Wiegand Stravenue",
"description": "exercises.Illo et velit quis fuga.",
"icon": "😳",
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage exercises",
"code": "GOALS:CREATE_EXERCISE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Exercise ID.
name
string
Exercise name.
description
string
Exercise description.
icon
string
Exercise icon identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update exercise
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/exercises/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Water plants\",
\"description\": \"Use Tripod Close Grip and water your plants\",
\"icon\": \"🪴\"
}"
const url = new URL(
"http://localhost:8000/api/exercises/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Water plants",
"description": "Use Tripod Close Grip and water your plants",
"icon": "🪴"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"name": "exercises.Benton Lane",
"description": "exercises.Dignissimos necessitatibus id temporibus ea at et cupiditate.",
"icon": "😶",
"created_at": "2026-09-22T11:26:32.000000Z",
"updated_at": "2026-09-22T11:26:32.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage exercises",
"code": "GOALS:UPDATE_EXERCISE:INSUFFICIENT_PERMISSION"
}
Example response (404, Exercise not found):
{
"message": "Exercise not found",
"code": "GOALS:UPDATE_EXERCISE:EXERCISE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Exercise ID.
name
string
Exercise name.
description
string
Exercise description.
icon
string
Exercise icon identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete exercise
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/exercises/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/exercises/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Exercise deleted",
"code": "GOALS:DELETE_EXERCISE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage exercises",
"code": "GOALS:DELETE_EXERCISE:INSUFFICIENT_PERMISSION"
}
Example response (403, Exercise is used in goals):
{
"message": "Cannot delete: exercise is used in goals (1)",
"code": "GOALS:DELETE_EXERCISE:HAS_GOALS"
}
Example response (404, Exercise not found):
{
"message": "Exercise not found",
"code": "GOALS:DELETE_EXERCISE:EXERCISE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List user goals
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1/goals?active=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/goals"
);
const params = {
"active": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"amputee_id": 263,
"clinician_id": 264,
"start_date": "1981-11-30",
"end_date": "2008-09-07",
"active": 0,
"created_at": "2026-09-22T11:26:33.000000Z",
"updated_at": "2026-09-22T11:26:33.000000Z"
},
{
"id": 2,
"amputee_id": 265,
"clinician_id": 266,
"start_date": "1991-12-19",
"end_date": "2017-11-06",
"active": 0,
"created_at": "2026-09-22T11:26:34.000000Z",
"updated_at": "2026-09-22T11:26:34.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view user goals",
"code": "GOALS:LIST_GOALS:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:LIST_GOALS:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Goal ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
start_date
string
Goal start date.
end_date
string
Goal end date.
active
boolean
Whether the goal is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create user goal
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/goals" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"start_date\": \"2023-05-12\",
\"end_date\": \"2023-05-15\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/user/1/goals"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"start_date": "2023-05-12",
"end_date": "2023-05-15",
"active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"amputee_id": 267,
"clinician_id": 268,
"start_date": "2022-01-05",
"end_date": "2016-12-10",
"active": 0,
"created_at": "2026-09-22T11:26:35.000000Z",
"updated_at": "2026-09-22T11:26:35.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user goals",
"code": "GOALS:CREATE_GOAL:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:CREATE_GOAL:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Goal ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
start_date
string
Goal start date.
end_date
string
Goal end date.
active
boolean
Whether the goal is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update user goal
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/user/1/goals/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"start_date\": \"2023-05-12\",
\"end_date\": \"2023-05-15\",
\"active\": true
}"
const url = new URL(
"http://localhost:8000/api/user/1/goals/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"start_date": "2023-05-12",
"end_date": "2023-05-15",
"active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"amputee_id": 269,
"clinician_id": 270,
"start_date": "1995-09-09",
"end_date": "2006-02-06",
"active": 1,
"created_at": "2026-09-22T11:26:36.000000Z",
"updated_at": "2026-09-22T11:26:36.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user goals",
"code": "GOALS:UPDATE_GOAL:INSUFFICIENT_PERMISSION"
}
Example response (403, Cannot activate ongoing goal):
{
"message": "Cannot activate ongoing goal",
"code": "GOALS:UPDATE_GOAL:GOAL_IS_ONGOING"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:UPDATE_GOAL:USER_NOT_FOUND"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:UPDATE_GOAL:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Goal ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
start_date
string
Goal start date.
end_date
string
Goal end date.
active
boolean
Whether the goal is active.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete user goal
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/user/1/goals/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/goals/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Goal deleted",
"code": "GOALS:DELETE_GOAL:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user goals",
"code": "GOALS:DELETE_GOAL:INSUFFICIENT_PERMISSION"
}
Example response (403, Cannot delete ongoing goal):
{
"message": "Cannot delete active ongoing goal",
"code": "GOALS:DELETE_GOAL:GOAL_IS_ONGOING"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:DELETE_GOAL:USER_NOT_FOUND"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:DELETE_GOAL:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List user goal conditions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1/goals/1/conditions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/goals/1/conditions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"goal_id": 5,
"type": "exercise",
"grip_id": 3,
"grips_frequency": "a",
"grips_count": 263,
"switches_frequency": "a",
"switches_count": 620,
"exercise_id": 5,
"exercise_frequency": "m",
"exercise_count": 9,
"created_at": "2026-09-22T11:26:37.000000Z",
"updated_at": "2026-09-22T11:26:37.000000Z"
},
{
"id": 2,
"goal_id": 6,
"type": "grip",
"grip_id": 4,
"grips_frequency": "m",
"grips_count": 465,
"switches_frequency": "m",
"switches_count": 138,
"exercise_id": 6,
"exercise_frequency": "w",
"exercise_count": 2,
"created_at": "2026-09-22T11:26:38.000000Z",
"updated_at": "2026-09-22T11:26:38.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view user goals",
"code": "GOALS:LIST_CONDITIONS:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:LIST_CONDITIONS:USER_NOT_FOUND"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:LIST_CONDITIONS:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Goal condition ID.
goal_id
integer
Associated goal ID.
type
string
Condition type.
Must be one of:gripswitchexercise
grip_id
integer
Target grip ID.
grips_frequency
string
Grip frequency period.
Must be one of:dwma
grips_count
integer
Required grip count.
switches_frequency
string
Switch frequency period.
Must be one of:dwma
switches_count
integer
Required switch count.
exercise_id
integer
Target exercise ID.
exercise_frequency
string
Exercise frequency period.
Must be one of:dwm
exercise_count
integer
Required exercise count.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create user goal condition
requires authentication
Each goal condition could be one of type: grip, switch or exercise.
If goal condition is type of grip, fill only grip_id (optional), grips_frequency and grips_count.
If grip_id is null or missing, patient can perform any grip to fulfill objective.
If goal condition is type of switch, fill only switches_frequency and switches_count.
If goal condition is type of exercise, fill only exercise_id, exercise_frequency and exercise_count.
Restrictions:
- you can add one grip-any condition (
grip_id=null, any grip is counted) and many grip-specific conditions (for example: grip 1 - 100 times and grip 2 - 50 times), - all grips conditions must have same frequency (
grips_frequencyfield), - sum of grip-specific conditions (
grips_countfield) cannot be greater than grip-any condition for same goal - you can add only one switch condition for same goal,
- you can add multiple exercise conditions, but each exercise can be used only once.
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/goals/1/conditions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"grip\",
\"grip_id\": 1,
\"grips_frequency\": \"d\",
\"grips_count\": 100,
\"switches_frequency\": \"d\",
\"switches_count\": 100,
\"exercise_id\": 1,
\"exercise_frequency\": \"d\",
\"exercise_count\": 5
}"
const url = new URL(
"http://localhost:8000/api/user/1/goals/1/conditions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "grip",
"grip_id": 1,
"grips_frequency": "d",
"grips_count": 100,
"switches_frequency": "d",
"switches_count": 100,
"exercise_id": 1,
"exercise_frequency": "d",
"exercise_count": 5
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"goal_id": 7,
"type": "grip",
"grip_id": 5,
"grips_frequency": "w",
"grips_count": 155,
"switches_frequency": "w",
"switches_count": 788,
"exercise_id": 7,
"exercise_frequency": "m",
"exercise_count": 3,
"created_at": "2026-09-22T11:26:39.000000Z",
"updated_at": "2026-09-22T11:26:39.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user goals",
"code": "GOALS:CREATE_CONDITION:INSUFFICIENT_PERMISSION"
}
Example response (403, Cannot create condition: all grip conditions have to be same frequency):
{
"message": "Cannot create condition: all grip conditions have to be same frequency",
"code": "GOALS:CREATE_CONDITION:INVALID_FREQUENCY"
}
Example response (403, Cannot create condition: grip-any condition for this goal already exist):
{
"message": "Cannot create condition: grip-any condition for this goal already exist",
"code": "GOALS:CREATE_CONDITION:GRIP_ANY_ALREADY_EXISTS"
}
Example response (403, Cannot create condition: condition with this grip already exist):
{
"message": "Cannot create condition: condition with this grip already exist",
"code": "GOALS:CREATE_CONDITION:GRIP_CONDITION_ALREADY_EXISTS"
}
Example response (403, Cannot create condition: grip-any value cannot be lower than sum of grip-specific conditions):
{
"message": "Cannot create condition: grip-any value cannot be lower than sum of grip-specific conditions",
"code": "GOALS:CREATE_CONDITION:GRIP_ANY_LOWER_THAN_GRIPS_SUM"
}
Example response (403, Cannot create condition: sum of grip-specific conditions cannot be greater than value of grip-any condition):
{
"message": "Cannot create condition: sum of grip-specific conditions cannot be greater than value of grip-any condition",
"code": "GOALS:CREATE_CONDITION:GRIPS_SUM_GREATER_THAN_GRIP_ANY"
}
Example response (403, Cannot create condition: switch condition for this goal already exist):
{
"message": "Cannot create condition: switch condition for this goal already exist",
"code": "GOALS:CREATE_CONDITION:SWITCH_CONDITION_ALREADY_EXISTS"
}
Example response (403, Cannot create condition: condition with this exercise already exist):
{
"message": "Cannot create condition: condition with this exercise already exist",
"code": "GOALS:CREATE_CONDITION:EXERCISE_CONDITION_ALREADY_EXISTS"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:CREATE_CONDITION:USER_NOT_FOUND"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:CREATE_CONDITION:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Goal condition ID.
goal_id
integer
Associated goal ID.
type
string
Condition type.
Must be one of:gripswitchexercise
grip_id
integer
Target grip ID.
grips_frequency
string
Grip frequency period.
Must be one of:dwma
grips_count
integer
Required grip count.
switches_frequency
string
Switch frequency period.
Must be one of:dwma
switches_count
integer
Required switch count.
exercise_id
integer
Target exercise ID.
exercise_frequency
string
Exercise frequency period.
Must be one of:dwm
exercise_count
integer
Required exercise count.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete user goal condition
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/user/1/goals/1/conditions/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/goals/1/conditions/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Goal condition deleted",
"code": "GOALS:DELETE_CONDITION:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user goals",
"code": "GOALS:DELETE_CONDITION:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "GOALS:DELETE_CONDITION:USER_NOT_FOUND"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:DELETE_CONDITION:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get user goal progress
requires authentication
grips- data about grips progress,switches- data about switches progress,exercises- data about exercises progress and attempts made.
overall- summary of whole goal time-frame,period- summary of given period, according to frequency (for example: if frequency of conditions is "weekly", these data is summary of current's week).today- summary of today's, used mainly to send daily summary notifications,conditions- goal conditions with progress for each one.
typefor grips overall summary, which points which conditions were used to calculate the summary. If grip-any condition exists, it has priority over grip-specific conditions, otherwise summary contains sum of all grip-specific conditions,frequency,frequency_fromandfrequency_tofor period summary for both grips and switches, which describe time-frame of frequency and period,donefor today's summary for both grips and switches, indicates if today's goal is reached (it's calculated only for conditions of frequency "daily").
Example request:
curl --request GET \
--get "http://localhost:8000/api/goals/1/progress" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/goals/1/progress"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"grips": {
"meta": {
"overall": {
"from": "2023-09-01 00:00:00",
"to": "2023-08-30 23:59:59"
},
"period": {
"from": "2023-09-15 23:59:59",
"to": "2023-09-21 23:59:59",
"frequency": "w"
}
},
"summary": {
"type": "grips-specific",
"progress": 222,
"goal": 2535
},
"progress": [
{
"grip": {
"id": 1,
"number": 0,
"name": "Rest Opposition",
"description": null,
"created_at": "2023-08-30T12:20:00.000000Z",
"updated_at": "2023-08-30T12:20:00.000000Z"
},
"overall": {
"progress": 125,
"goal": 200
},
"period": {
"progress": 22,
"goal": 50
}
},
{
"grip": {
"id": 2,
"number": 1,
"name": "Power",
"description": null,
"created_at": "2023-05-18T11:24:11.000000Z",
"updated_at": "2023-05-18T11:24:11.000000Z"
},
"overall": {
"progress": 90,
"goal": 150
},
"period": {
"progress": 10,
"goal": 30
}
},
{
"grip": null,
"overall": {
"progress": 78,
"goal": 1250
},
"period": {
"progress": 17,
"goal": 240
}
}
],
"today": {
"performed": 0,
"goal": 0,
"done": true
}
},
"switches": {
"overall": {
"performed": 55,
"goal": 300
},
"period": {
"performed": 25,
"goal": 30,
"frequency": "d",
"frequency_from": "2023-09-20 00:00:00",
"frequency_to": "2023-09-20 23:59:59"
},
"today": {
"performed": 25,
"goal": 30,
"done": false
},
"condition": {
"type": "switch",
"switches_frequency": "d",
"switches_count": 30
}
},
"exercises": {
"performed": 1,
"goal": 3,
"done": false,
"conditions": [
{
"type": "exercise",
"exercise_id": 1,
"exercise_frequency": "d",
"exercise_count": 3,
"attempts": [
{
"date_from": "2023-06-06",
"date_to": "2023-06-12",
"count_done": 1,
"count_not_done": 1
},
{
"date_from": "2023-06-13",
"date_to": "2023-06-19",
"count_done": 0,
"count_not_done": 0
},
{
"date_from": "2023-06-20",
"date_to": "2023-06-26",
"count_done": 0,
"count_not_done": 0
},
{
"date_from": "2023-06-27",
"date_to": "2023-07-03",
"count_done": 0,
"count_not_done": 0
}
],
"exercise": {
"id": 1,
"name": "Water plants",
"description": "Use Tripod Grip and water your plants",
"icon": "🪴",
"created_at": "2023-05-19T10:25:37.000000Z",
"updated_at": "2023-05-19T10:25:37.000000Z"
}
}
]
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view goal progress",
"code": "GOALS:GET_PROGRESS:INSUFFICIENT_PERMISSION"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:GET_PROGRESS:GOAL_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update user goal progress
requires authentication
Use this endpoint to update goal progress as patient. Add exercise attempts and mark them as done or not done.
Example request:
curl --request POST \
"http://localhost:8000/api/goals/1/progress" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"exercise_id\": 1,
\"exercise_done\": true
}"
const url = new URL(
"http://localhost:8000/api/goals/1/progress"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"exercise_id": 1,
"exercise_done": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 1,
"user_id": 277,
"goal_id": 8,
"type": "switch",
"grip_id": null,
"grips": 63,
"switches": 518,
"exercise_id": 8,
"exercise_done": 0,
"created_at": "2026-09-22T11:26:40.000000Z",
"updated_at": "2026-09-22T11:26:40.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update goal progress",
"code": "GOALS:UPDATE_PROGRESS:INSUFFICIENT_PERMISSION"
}
Example response (404, Goal not found):
{
"message": "Goal not found",
"code": "GOALS:UPDATE_PROGRESS:GOAL_NOT_FOUND"
}
Example response (422, User timezone not set):
{
"message": "User timezone not set",
"code": "GOALS:UPDATE_PROGRESS:NO_TIMEZONE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User goal ID.
user_id
integer
Associated user ID.
goal_id
integer
Associated goal ID.
type
string
Goal condition type.
Must be one of:gripswitchexercise
grip_id
integer
Target grip ID.
grips
integer
Grip count progress.
switches
integer
Switch count progress.
exercise_id
integer
Target exercise ID.
exercise_done
boolean
Whether the exercise is completed.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Invitations
Accept clinician invitation
Example request:
curl --request POST \
"http://localhost:8000/api/invite/accept" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token\": \"ABC123DEF456GHI789JKL0\",
\"email\": \"example@domain.com\",
\"password\": \"Test123!\",
\"language\": \"en\",
\"name\": \"Tom Smith\",
\"clinic_name\": \"My clinic Ltd\",
\"clinic_location\": \"Example St 1\\/345 New York, NY\",
\"address1\": \"11490 Little Pass Apt. 427\",
\"address2\": \"East Newell, UT 29284-4448\",
\"mfa_enabled\": true,
\"mfa_method\": \"email\"
}"
const url = new URL(
"http://localhost:8000/api/invite/accept"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token": "ABC123DEF456GHI789JKL0",
"email": "example@domain.com",
"password": "Test123!",
"language": "en",
"name": "Tom Smith",
"clinic_name": "My clinic Ltd",
"clinic_location": "Example St 1\/345 New York, NY",
"address1": "11490 Little Pass Apt. 427",
"address2": "East Newell, UT 29284-4448",
"mfa_enabled": true,
"mfa_method": "email"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 4,
"mrn": "QZE8U48G1790076258",
"name": "Tara Gutkowski",
"email": "1790076258uwolff@example.org",
"language": "en",
"phone": "(808) 671-2686",
"phone_country": "MP",
"phone_verified_at": null,
"address1": "49266 Collins Mountains",
"address2": "Ferrybury, SC 40203",
"postal_code": "98732-5388",
"city": "Altenwerth-Raynor",
"country": "NL",
"clinic_name": "New Angelo",
"clinic_location": "34102 Marks Brooks\nPort Kobe, AK 21120",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:18.000000Z",
"updated_at": "2026-09-22T11:24:18.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 5,
"name": "ClinicianSupport"
}
]
}
Example response (403, Invitation expired):
{
"message": "Invitation expired",
"code": "INVITATIONS:ACCEPT:INVITATION_EXPIRED"
}
Example response (404, Invitation not found):
{
"message": "Invitation not found",
"code": "INVITATIONS:ACCEPT:INVITATION_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: invitation not accepted",
"code": "INVITATIONS:ACCEPT:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Accept Acadle invitation
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/invite/acadle/accept" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token\": \"a1b2c3d4e5f6g7h8i9j0k1l2m3\",
\"email\": \"user@example.com\",
\"password\": \"securePassword123\",
\"phone\": \"+1-223-645-9412\",
\"phone_country\": \"US\",
\"name\": \"John Doe\",
\"language\": \"en\"
}"
const url = new URL(
"http://localhost:8000/api/invite/acadle/accept"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token": "a1b2c3d4e5f6g7h8i9j0k1l2m3",
"email": "user@example.com",
"password": "securePassword123",
"phone": "+1-223-645-9412",
"phone_country": "US",
"name": "John Doe",
"language": "en"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 5,
"mrn": "F445SW5G1790076259",
"name": "Kamron Cronin Sr.",
"email": "1790076259cwest@example.com",
"language": "en",
"phone": "1-480-742-8219",
"phone_country": "PE",
"phone_verified_at": null,
"address1": "53174 Myrtle Brooks",
"address2": "Donnellyberg, OR 06104",
"postal_code": "52261-4620",
"city": "Metz, Berge and Hegmann",
"country": "GR",
"clinic_name": "Port Manley",
"clinic_location": "161 Klein Greens Suite 086\nEast Wilsonton, NH 13267",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:19.000000Z",
"updated_at": "2026-09-22T11:24:19.000000Z",
"invitation_status": null,
"acadle_invitation_status": "accepted",
"roles": [
{
"id": 7,
"name": "AcadleUser"
}
]
}
Example response (403, Invitation expired):
{
"message": "Invitation expired",
"code": "INVITATIONS_ACADLE:ACCEPT:INVITATION_EXPIRED"
}
Example response (404, Invitation not found):
{
"message": "Invitation not found",
"code": "INVITATIONS_ACADLE:ACCEPT:INVITATION_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: invitation not accepted",
"code": "INVITATIONS_ACADLE:ACCEPT:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
List users for invitations
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/invite/users" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/invite/users"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 15,
"mrn": "63PUQY9V1790076264",
"name": "Meagan Schmitt",
"email": "1790076264corkery.eudora@example.com",
"language": "en",
"phone": "458.502.7867",
"phone_country": "IQ",
"phone_verified_at": null,
"address1": "1870 Enrique Cape Suite 322",
"address2": "Kylaport, AZ 53164-4063",
"postal_code": "81615-1957",
"city": "Zieme, Miller and Wisozk",
"country": "RO",
"clinic_name": "Durganbury",
"clinic_location": "787 Schumm Union Apt. 886\nNorth Barbara, AK 48174",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 4,
"name": "Clinician"
}
]
},
{
"id": 16,
"mrn": "AQQ9HNE81790076265",
"name": "Zelma Gislason",
"email": "1790076265elody.miller@example.net",
"language": "en",
"phone": "1-325-201-7097",
"phone_country": "FO",
"phone_verified_at": null,
"address1": "59594 Ena Courts",
"address2": "Binsport, KS 53491-6647",
"postal_code": "35263",
"city": "Gerlach-Schmitt",
"country": "HU",
"clinic_name": "West Kimberly",
"clinic_location": "47958 Laverne Track\nSouth Gustaveton, GA 80616",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:25.000000Z",
"updated_at": "2026-09-22T11:24:25.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 3,
"name": "ClinicAdmin"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list users for invitations",
"code": "INVITATIONS:USERS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create clinician invitations
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/invite" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"patient_id\": 1,
\"invitations\": [
{
\"user_id\": 1,
\"user_email\": \"newuser@domain.com\",
\"role\": \"Clinician\",
\"training_confirmed\": true,
\"permissions\": [
\"doloremque\"
]
}
]
}"
const url = new URL(
"http://localhost:8000/api/invite"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"patient_id": 1,
"invitations": [
{
"user_id": 1,
"user_email": "newuser@domain.com",
"role": "Clinician",
"training_confirmed": true,
"permissions": [
"doloremque"
]
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 10,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 17,
"mrn": "62HS9XLZ1790076265",
"name": "Zula Becker",
"email": "1790076265champlin.cortney@example.org",
"language": "en",
"phone": "732-571-3737",
"phone_country": "PL",
"phone_verified_at": null,
"address1": "74085 Mraz Green",
"address2": "Ondrickaside, NJ 61219",
"postal_code": "87883",
"city": "Spencer and Sons",
"country": "US",
"clinic_name": "South Horacioton",
"clinic_location": "843 Tillman Cliffs\nWest Audrey, CT 68489-6166",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:25.000000Z",
"updated_at": "2026-09-22T11:24:25.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"invitations": [
{
"id": 1,
"user_id": 18,
"invited_user_id": 17,
"type": "clinician",
"training_confirmed": 0,
"created_at": "2026-09-22T11:24:26.000000Z",
"updated_at": "2026-09-22T11:24:26.000000Z"
}
],
"roles": [
{
"id": 1,
"name": "SuperAdmin"
}
]
},
{
"id": 20,
"mrn": "H5JTXLYJ1790076266",
"name": "Raoul Kris",
"email": "1790076266erunolfsson@example.com",
"language": "en",
"phone": "+1.619.512.1835",
"phone_country": "TT",
"phone_verified_at": null,
"address1": "557 Alaina Divide Suite 575",
"address2": "North Edwina, ME 78011-0887",
"postal_code": "14506",
"city": "Reynolds-Grant",
"country": "NO",
"clinic_name": "East Connorport",
"clinic_location": "7476 Jacobs Curve Suite 928\nTierraberg, OH 60543",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:26.000000Z",
"updated_at": "2026-09-22T11:24:26.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"invitations": [
{
"id": 2,
"user_id": 21,
"invited_user_id": 20,
"type": "clinician",
"training_confirmed": 0,
"created_at": "2026-09-22T11:24:28.000000Z",
"updated_at": "2026-09-22T11:24:28.000000Z"
}
],
"roles": [
{
"id": 3,
"name": "ClinicAdmin"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create invitations",
"code": "INVITATIONS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, No access to given patient):
{
"message": "No access to given patient",
"code": "INVITATIONS:CREATE:NO_ACCESS_TO_PATIENT"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Resend invitation
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/invite/1/resend" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/invite/1/resend"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 23,
"mrn": "5H4PU5GW1790076268",
"name": "Beverly Gaylord",
"email": "1790076268zhilpert@example.net",
"language": "en",
"phone": "+13367959393",
"phone_country": "PN",
"phone_verified_at": null,
"address1": "232 Jacobs Stravenue",
"address2": "East Vicentemouth, IL 56917",
"postal_code": "60680",
"city": "Carter Inc",
"country": "ES",
"clinic_name": "Linwoodchester",
"clinic_location": "76322 Kertzmann Shores Suite 937\nPort Dewitt, NM 86319-3800",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:28.000000Z",
"updated_at": "2026-09-22T11:24:28.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"invitations": [
{
"id": 3,
"user_id": 24,
"invited_user_id": 23,
"type": "clinician",
"training_confirmed": 1,
"created_at": "2026-09-22T11:24:29.000000Z",
"updated_at": "2026-09-22T11:24:29.000000Z"
}
],
"roles": [
{
"id": 5,
"name": "ClinicianSupport"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to resend invitations",
"code": "INVITATIONS:RESEND:INSUFFICIENT_PERMISSION"
}
Example response (403, User not found):
{
"message": "User not found",
"code": "INVITATIONS:RESEND:USER_NOT_FOUND"
}
Example response (403, Invitation already accepted):
{
"message": "Invitation already accepted",
"code": "INVITATIONS:RESEND:INVITATION_ALREADY_ACCEPTED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
List all users invited to Acadle
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/invite/acadle/users?search=john" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/invite/acadle/users"
);
const params = {
"search": "john",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 26,
"mrn": "XJ9RFD581790076269",
"name": "Prof. Helene Hintz",
"email": "1790076269dwilkinson@example.org",
"language": "en",
"phone": "678-951-7146",
"phone_country": "AT",
"phone_verified_at": null,
"address1": "80155 Casper Valley",
"address2": "East Charlotte, VT 43657-3847",
"postal_code": "01206",
"city": "Grimes, Bechtelar and Luettgen",
"country": "NO",
"clinic_name": "New Quinnstad",
"clinic_location": "625 Quitzon Islands\nLake Theresebury, KY 70516",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:29.000000Z",
"updated_at": "2026-09-22T11:24:29.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": [
{
"id": 2,
"name": "CommunityAdmin"
}
]
},
{
"id": 27,
"mrn": "56JVWC541790076269",
"name": "Dr. Dalton Nitzsche",
"email": "1790076269alex.huels@example.org",
"language": "en",
"phone": "1-786-923-2730",
"phone_country": "SD",
"phone_verified_at": null,
"address1": "2442 Hills Divide",
"address2": "Pricemouth, AK 31275",
"postal_code": "23936-0258",
"city": "Labadie-Lehner",
"country": "NL",
"clinic_name": "Cummingsside",
"clinic_location": "557 Violet Key\nNew Zander, ME 54695-4710",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:30.000000Z",
"updated_at": "2026-09-22T11:24:30.000000Z",
"invitation_status": null,
"acadle_invitation_status": "accepted",
"roles": [
{
"id": 7,
"name": "AcadleUser"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list users for invitations",
"code": "INVITATIONS_ACADLE:USERS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create Acadle invitation
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/invite/acadle" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"magnus.bauch@example.com\"
}"
const url = new URL(
"http://localhost:8000/api/invite/acadle"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "magnus.bauch@example.com"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 28,
"mrn": "9FZCZV271790076270",
"name": "Prof. Nikolas Veum DVM",
"email": "1790076270vallie58@example.net",
"language": "en",
"phone": "(860) 649-3420",
"phone_country": "CC",
"phone_verified_at": null,
"address1": "26731 Tony Points",
"address2": "Clintonmouth, ME 60616",
"postal_code": "13950-3370",
"city": "Walsh-Pfeffer",
"country": "IN",
"clinic_name": "Haventown",
"clinic_location": "93871 Harris Stream\nLake Sister, SC 70879",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:30.000000Z",
"updated_at": "2026-09-22T11:24:30.000000Z",
"invitation_status": null,
"acadle_invitation_status": "accepted",
"invitations": [
{
"id": 4,
"user_id": 29,
"invited_user_id": 28,
"type": "clinician",
"training_confirmed": 1,
"created_at": "2026-09-22T11:24:31.000000Z",
"updated_at": "2026-09-22T11:24:31.000000Z"
}
],
"roles": [
{
"id": 7,
"name": "AcadleUser"
}
]
}
Example response (400, User already exists):
{
"message": "User with this email already exists in the system",
"code": "INVITATIONS_ACADLE:CREATE:USER_ALREADY_EXISTS"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create invitations",
"code": "INVITATIONS_ACADLE:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Resend Acadle invitation
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/invite/acadle/1/resend" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/invite/acadle/1/resend"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 31,
"mrn": "GHMTNZAN1790076271",
"name": "Arlene Schaefer",
"email": "1790076271jaeden70@example.org",
"language": "en",
"phone": "+1-803-919-7680",
"phone_country": "ET",
"phone_verified_at": null,
"address1": "45256 Hodkiewicz Isle Suite 330",
"address2": "Arnaldobury, MS 62064-0735",
"postal_code": "42915-1692",
"city": "Konopelski LLC",
"country": "DE",
"clinic_name": "West Tommie",
"clinic_location": "12054 Boyer Fall Apt. 798\nLake Terrill, AR 82585",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:31.000000Z",
"updated_at": "2026-09-22T11:24:31.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"invitations": [
{
"id": 5,
"user_id": 32,
"invited_user_id": 31,
"type": "clinician",
"training_confirmed": 0,
"created_at": "2026-09-22T11:24:33.000000Z",
"updated_at": "2026-09-22T11:24:33.000000Z"
}
],
"roles": [
{
"id": 5,
"name": "ClinicianSupport"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to resend invitations",
"code": "INVITATIONS_ACADLE:RESEND:INSUFFICIENT_PERMISSION"
}
Example response (403, User not found):
{
"message": "User not found",
"code": "INVITATIONS_ACADLE:RESEND:USER_NOT_FOUND"
}
Example response (403, Invitation already accepted):
{
"message": "Invitation already accepted",
"code": "INVITATIONS_ACADLE:RESEND:INVITATION_ALREADY_ACCEPTED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Admin access to invitation tokens
requires authentication
Requires admin.invitations_tokens_access permission.
Fetches only non-accepted and non-expired invitations.
Example request:
curl --request GET \
--get "http://localhost:8000/api/invite/tokens/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/invite/tokens/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
[
{
"id": 1,
"user_id": 1,
"invited_user_id": 2,
"token": "I0V25NUVMHC0F8RRF1YEY5BT",
"training_confirmed": 1,
"created_at": "2025-05-12T12:00:00.000000Z",
"updated_at": "2025-05-12T12:00:00.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to get invitation tokens",
"code": "INVITATIONS:ADMIN_TOKENS:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "INVITATIONS:ADMIN_TOKENS:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logs
API endpoints for managing event logs
Get events log
requires authentication
user - user account that performed the action
element - element model that has been affected by the action
Example request:
curl --request GET \
--get "http://localhost:8000/api/logs?search=Test&ip=200.200.100.5&user=1&type=user&date_from=1642003200&date_to=1642003200&include_sessions=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
const url = new URL(
"http://localhost:8000/api/logs"
);
const params = {
"search": "Test",
"ip": "200.200.100.5",
"user": "1",
"type": "user",
"date_from": "1642003200",
"date_to": "1642003200",
"include_sessions": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"user_id": 282,
"event_name": "event_factory",
"element_type": "App\\Models\\User",
"element_id": 281,
"comments": "",
"ip_address": "250.12.20.180",
"created_at": "2011-03-24T04:22:08.000000Z",
"updated_at": "2026-09-22T11:26:42.000000Z",
"username": "Nestor Wiegand",
"user": {
"id": 282,
"mrn": "J5JUNRZP1790076401",
"name": "Nestor Wiegand",
"email": "1790076401ebergnaum@example.com",
"language": "en",
"phone": "+16202734615",
"phone_country": "TR",
"phone_verified_at": null,
"address1": "8984 Peyton Gateway Suite 251",
"address2": "Lake Rosa, AR 48869",
"postal_code": "78350-1502",
"city": "Bogan-Schneider",
"country": "UA",
"clinic_name": "Mitchellton",
"clinic_location": "78322 Era Villages\nSouth Darionborough, SC 73932",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:41.000000Z",
"updated_at": "2026-09-22T11:26:41.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"element": {
"id": 281,
"mrn": "V4HMMF8Q1790076401",
"name": "Stanley Rutherford",
"email": "1790076401trowe@example.com",
"language": "en",
"phone": "(925) 861-3439",
"phone_country": "KM",
"phone_verified_at": null,
"address1": "674 Justyn Heights Suite 961",
"address2": "Darrinton, MN 34852-1823",
"postal_code": "89416-7857",
"city": "Gerhold Ltd",
"country": "LV",
"clinic_name": "New Mavisborough",
"clinic_location": "24539 Sigurd River\nWest Theodoremouth, ID 01230-6141",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:41.000000Z",
"updated_at": "2026-09-22T11:26:41.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
},
{
"id": 2,
"user_id": 285,
"event_name": "event_factory",
"element_type": "App\\Models\\User",
"element_id": 284,
"comments": "",
"ip_address": "122.69.85.206",
"created_at": "1994-09-16T19:37:39.000000Z",
"updated_at": "2026-09-22T11:26:43.000000Z",
"username": "Duncan Kunze",
"user": {
"id": 285,
"mrn": "KBQT5ZDK1790076403",
"name": "Duncan Kunze",
"email": "1790076403xbeier@example.org",
"language": "en",
"phone": "+1 (862) 497-1102",
"phone_country": "WS",
"phone_verified_at": null,
"address1": "673 Bernie Overpass",
"address2": "Billieside, SD 52708-6154",
"postal_code": "37496",
"city": "Doyle-Larkin",
"country": "ES",
"clinic_name": "Allanton",
"clinic_location": "7388 Shakira Parkway Suite 882\nChaimton, MI 89671",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:43.000000Z",
"updated_at": "2026-09-22T11:26:43.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"element": {
"id": 284,
"mrn": "ZLYBM48G1790076402",
"name": "Erin Macejkovic",
"email": "1790076402stuart.kutch@example.org",
"language": "en",
"phone": "520-421-8646",
"phone_country": "DO",
"phone_verified_at": null,
"address1": "53631 Cletus Street",
"address2": "Kenyonport, AL 92511-4752",
"postal_code": "13956-0275",
"city": "Flatley-Bogisich",
"country": "DE",
"clinic_name": "Port Tyson",
"clinic_location": "199 Lenna Terrace Suite 838\nMontyton, MT 03547-4729",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:42.000000Z",
"updated_at": "2026-09-22T11:26:42.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access event logs",
"code": "EVENT_LOGS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Event log entry ID.
user_id
integer
ID of the user who triggered the event.
event_name
string
Event name.
element_type
string
Type of the related element.
element_id
integer
ID of the related element.
comments
string
Additional event comments.
ip_address
string
IP address of the request.
created_at
string
Event timestamp.
updated_at
string
Last update timestamp.
user
object
User who triggered the event.
element
object
Related element.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Messages
API endpoints for message center
Get user messages list
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/messages" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"filter\": \"all\"
}"
const url = new URL(
"http://localhost:8000/api/messages"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"filter": "all"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"user_id": null,
"message_id": 1,
"is_read": 0,
"is_archived": 0,
"is_deleted": 0,
"message": {
"id": 1,
"sender_id": null,
"title": "Modi dolorem possimus velit sunt.",
"content": "Eligendi repudiandae voluptatem saepe minima eligendi.",
"created_at": "2026-09-22T11:25:32.000000Z",
"updated_at": "2026-09-22T11:25:32.000000Z",
"sender": null
}
},
{
"id": 2,
"user_id": null,
"message_id": 2,
"is_read": 0,
"is_archived": 0,
"is_deleted": 0,
"message": {
"id": 2,
"sender_id": null,
"title": "Animi laborum in dolorem.",
"content": "Nesciunt omnis quia et vero placeat totam neque.",
"created_at": "2026-09-22T11:25:32.000000Z",
"updated_at": "2026-09-22T11:25:32.000000Z",
"sender": null
}
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User message ID.
user_id
integer
Recipient user ID.
message_id
integer
Associated message ID.
is_read
boolean
Whether the message has been read.
is_archived
boolean
Whether the message is archived.
is_deleted
boolean
Whether the message is deleted.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
message
object
The message content.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Send message to multiple users
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/message" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"title\": \"Reminder about your vaccination\",
\"content\": \"Lorem ipsum dolor sit amet\",
\"roles\": \"Clinician,Amputee\"
}"
const url = new URL(
"http://localhost:8000/api/message"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"title": "Reminder about your vaccination",
"content": "Lorem ipsum dolor sit amet",
"roles": "Clinician,Amputee"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"message": "Messages sent",
"count": 3,
"code": "MESSAGES:SEND:SENT"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to send messages",
"code": "MESSAGES:SEND:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Mark message as read
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/message/1/read" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"state\": true
}"
const url = new URL(
"http://localhost:8000/api/message/1/read"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"state": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 3,
"user_id": 148,
"message_id": 3,
"is_read": 0,
"is_archived": 0,
"is_deleted": 0
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to mark this message as read",
"code": "MESSAGES:READ:INSUFFICIENT_PERMISSION"
}
Example response (404, Message not found):
{
"message": "Message not found",
"code": "MESSAGES:READ:MESSAGE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User message ID.
user_id
integer
Recipient user ID.
message_id
integer
Associated message ID.
is_read
boolean
Whether the message has been read.
is_archived
boolean
Whether the message is archived.
is_deleted
boolean
Whether the message is deleted.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
message
object
The message content.
Mark message as archived
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/message/1/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"state\": true
}"
const url = new URL(
"http://localhost:8000/api/message/1/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"state": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"user_id": 149,
"message_id": 4,
"is_read": 0,
"is_archived": 0,
"is_deleted": 0
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to mark this message as archived",
"code": "MESSAGES:ARCHIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Message not found):
{
"message": "Message not found",
"code": "MESSAGES:ARCHIVE:MESSAGE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User message ID.
user_id
integer
Recipient user ID.
message_id
integer
Associated message ID.
is_read
boolean
Whether the message has been read.
is_archived
boolean
Whether the message is archived.
is_deleted
boolean
Whether the message is deleted.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
message
object
The message content.
List of messages and tickets
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/messages-and-tickets" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/messages-and-tickets"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 2
},
"items": [
{
"type": "UserMessage",
"date": "2024-11-02T10:00:00.000000Z",
"item": {
"id": 1,
"user_id": 1,
"message_id": 1,
"is_read": 0,
"is_archived": 0,
"is_deleted": 0,
"message": {
"id": 1,
"sender_id": 1,
"title": "Message title",
"content": "Message content",
"created_at": "2024-11-02T10:00:00.000000Z",
"updated_at": "2024-11-02T10:00:00.000000Z",
"sender": {
"id": 1,
"mrn": "MRN",
"name": "User name",
"email": "user@domain.com",
"language": "en",
"phone": "",
"phone_verified_at": null,
"address1": "",
"address2": "",
"postal_code": "",
"city": "",
"clinic_name": "Test Company",
"clinic_location": "Test Company Location",
"image": null,
"mfa_enabled": 0,
"mfa_method": "email",
"mfa_verified_to": null,
"created_by": null,
"active": 1,
"notifications_timezone": "Europe/Warsaw",
"notifications_at": "08:00:00",
"created_at": "2024-09-01T15:00:00.000000Z",
"updated_at": "2024-10-10T10:30:00.000000Z",
"invitation_status": "accepted",
"roles": [
{
"id": 3,
"name": "Clinician",
"guard_name": "web",
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z",
"pivot": {
"model_id": 1,
"role_id": 3,
"model_type": "App\\Models\\User"
}
}
]
}
}
}
},
{
"type": "SupportTicket",
"date": "2024-11-01T15:15:00.000000Z",
"item": {
"id": 1,
"sender_id": 1,
"recipient_id": 999,
"device_id": null,
"meeting_date": "2024-11-10T15:00:00.000000Z",
"meeting_type": "none",
"contact_email": null,
"status": "new",
"created_at": "2024-11-01T15:15:00.000000Z",
"updated_at": "2024-11-01T15:15:00.000000Z",
"sender": {
"id": 1,
"mrn": "MRN",
"name": "User name",
"email": "user@domain.com",
"language": "en",
"phone": "",
"phone_verified_at": null,
"address1": "",
"address2": "",
"postal_code": "",
"city": "",
"clinic_name": "Test Company",
"clinic_location": "Test Company Location",
"image": null,
"mfa_enabled": 0,
"mfa_method": "email",
"mfa_verified_to": null,
"created_by": null,
"active": 1,
"notifications_timezone": "Europe/Warsaw",
"notifications_at": "08:00:00",
"created_at": "2024-09-01T15:00:00.000000Z",
"updated_at": "2024-10-10T10:30:00.000000Z",
"invitation_status": "accepted",
"roles": [
{
"id": 3,
"name": "Clinician",
"guard_name": "web",
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z",
"pivot": {
"model_id": 1,
"role_id": 3,
"model_type": "App\\Models\\User"
}
}
]
},
"recipient": {
"id": 2,
"mrn": "MRN2",
"name": "Patient",
"email": "patient4@domain.com",
"language": "en",
"phone": "",
"phone_verified_at": null,
"address1": "",
"address2": "",
"postal_code": "",
"city": "",
"clinic_name": null,
"clinic_location": null,
"image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"created_by": 1,
"active": 1,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2024-10-01T15:00:00.000000Z",
"updated_at": "2024-10-10T10:30:00.000000Z",
"invitation_status": null,
"roles": [
{
"id": 5,
"name": "Amputee",
"guard_name": "web",
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z",
"pivot": {
"model_id": 2,
"role_id": 5,
"model_type": "App\\Models\\User"
}
}
]
},
"device": null,
"messages": [
{
"id": 1,
"ticket_id": 1,
"sender_id": 1,
"title": "Communication channel",
"content": "Welcome to the digital platform. Please use this channel for communicating with your clinician.",
"is_read": false,
"created_at": "2024-11-01T15:15:00.000000Z",
"updated_at": "2024-11-01T15:15:00.000000Z",
"attachments": [],
"sender": {
"id": 1,
"mrn": "MRN",
"name": "User name",
"email": "user@domain.com",
"language": "en",
"phone": "",
"phone_verified_at": null,
"address1": "",
"address2": "",
"postal_code": "",
"city": "",
"clinic_name": "Test Company",
"clinic_location": "Test Company Location",
"image": null,
"mfa_enabled": 0,
"mfa_method": "email",
"mfa_verified_to": null,
"created_by": null,
"active": 1,
"notifications_timezone": "Europe/Warsaw",
"notifications_at": "08:00:00",
"created_at": "2024-09-01T15:00:00.000000Z",
"updated_at": "2024-10-10T10:30:00.000000Z",
"invitation_status": "accepted",
"roles": [
{
"id": 3,
"name": "Clinician",
"guard_name": "web",
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z",
"pivot": {
"model_id": 1,
"role_id": 3,
"model_type": "App\\Models\\User"
}
}
]
}
}
]
}
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Status of messages and tickets
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/messages-and-tickets/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/messages-and-tickets/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"messages": 5,
"tickets": 2
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Mobile logs
API endpoints for managing mobile logs
Store log
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/mobile-logs" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "device_id=1"\
--form "date_start=1985-06-07 08:54:19"\
--form "date_end=1971-08-11 15:26:30"\
--form "encrypt_key=sit"\
--form "encrypt_iv=sint"\
--form "file=@/tmp/phpXCi9ie" const url = new URL(
"http://localhost:8000/api/mobile-logs"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('device_id', '1');
body.append('date_start', '1985-06-07 08:54:19');
body.append('date_end', '1971-08-11 15:26:30');
body.append('encrypt_key', 'sit');
body.append('encrypt_iv', 'sint');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (202):
{
"id": 1,
"user_id": 286,
"device_id": 147,
"file": "/tmp/faker3OQwvr",
"date_start": "1987-09-13 05:23:03",
"date_end": "1992-03-02 08:55:13",
"created_at": "2026-09-22T11:26:44.000000Z",
"updated_at": "2026-09-22T11:26:44.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to write mobile logs",
"code": "MOBILE_LOGS:STORE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Mobile log ID.
user_id
integer
Associated user ID.
device_id
integer
Associated device ID.
file
string
Log file URL.
date_start
string
Log start date.
date_end
string
Log end date.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Get logs
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/mobile-logs" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mobile-logs"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 2,
"user_id": 287,
"device_id": 148,
"file": "/tmp/fakerlQ9CQr",
"date_start": "2003-03-11 05:51:53",
"date_end": "2014-09-22 01:34:08",
"created_at": "2026-09-22T11:26:44.000000Z",
"updated_at": "2026-09-22T11:26:44.000000Z"
},
{
"id": 3,
"user_id": 288,
"device_id": 149,
"file": "/tmp/fakere9vzVO",
"date_start": "2012-03-07 21:28:21",
"date_end": "2006-07-16 22:14:36",
"created_at": "2026-09-22T11:26:45.000000Z",
"updated_at": "2026-09-22T11:26:45.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view mobile logs",
"code": "MOBILE_LOGS:GET:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Mobile log ID.
user_id
integer
Associated user ID.
device_id
integer
Associated device ID.
file
string
Log file URL.
date_start
string
Log start date.
date_end
string
Log end date.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get logs by user
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/mobile-logs/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mobile-logs/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 4,
"user_id": 289,
"device_id": 150,
"file": "/tmp/fakerY4n1vq",
"date_start": "1986-04-12 22:39:37",
"date_end": "1993-12-25 07:55:59",
"created_at": "2026-09-22T11:26:45.000000Z",
"updated_at": "2026-09-22T11:26:45.000000Z"
},
{
"id": 5,
"user_id": 290,
"device_id": 151,
"file": "/tmp/fakerM2ZU6u",
"date_start": "1982-02-16 09:54:04",
"date_end": "1998-10-24 23:19:29",
"created_at": "2026-09-22T11:26:46.000000Z",
"updated_at": "2026-09-22T11:26:46.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view mobile logs",
"code": "MOBILE_LOGS:GET_BY_USER:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Mobile log ID.
user_id
integer
Associated user ID.
device_id
integer
Associated device ID.
file
string
Log file URL.
date_start
string
Log start date.
date_end
string
Log end date.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get logs by device
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/mobile-logs/device/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mobile-logs/device/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 6,
"user_id": 291,
"device_id": 152,
"file": "/tmp/fakervF4H9Y",
"date_start": "1973-05-16 18:15:46",
"date_end": "1989-01-27 23:20:20",
"created_at": "2026-09-22T11:26:46.000000Z",
"updated_at": "2026-09-22T11:26:46.000000Z"
},
{
"id": 7,
"user_id": 292,
"device_id": 153,
"file": "/tmp/fakerp1xyFz",
"date_start": "2013-04-06 09:29:50",
"date_end": "1979-05-09 22:59:20",
"created_at": "2026-09-22T11:26:47.000000Z",
"updated_at": "2026-09-22T11:26:47.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view mobile logs",
"code": "MOBILE_LOGS:GET_BY_DEVICE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Mobile log ID.
user_id
integer
Associated user ID.
device_id
integer
Associated device ID.
file
string
Log file URL.
date_start
string
Log start date.
date_end
string
Log end date.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Old Configurator Statistics
Endpoints for old configurator statistics
Create old configurator statistic
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/old-configurator-statistics" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"entry_id\": \"quaerat\",
\"comments\": \"maxime\"
}"
const url = new URL(
"http://localhost:8000/api/old-configurator-statistics"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"entry_id": "quaerat",
"comments": "maxime"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"entry_id": "026a2899-5d07-3ebb-a1e7-b63dae3de602",
"comments": "{\"key\":\"esse\",\"value\":2793}",
"created_at": "2026-09-22T11:24:20.000000Z",
"updated_at": "2026-09-22T11:24:20.000000Z"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List old configurator statistics
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/old-configurator-statistics" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/old-configurator-statistics"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 2,
"entry_id": "2c3bcad4-8a33-3a26-a085-9590e6998931",
"comments": "{\"key\":\"fuga\",\"value\":45647}",
"created_at": "2026-09-22T11:27:09.000000Z",
"updated_at": "2026-09-22T11:27:09.000000Z"
},
{
"id": 3,
"entry_id": "db7168bc-3d2a-3e80-baef-4ee91f906b8b",
"comments": "{\"key\":\"suscipit\",\"value\":97676}",
"created_at": "2026-09-22T11:27:09.000000Z",
"updated_at": "2026-09-22T11:27:09.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view old configurator statistics",
"code": "OLD_CONFIGURATOR_STATISTIC:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
P2P Sessions
API endpoints for managing P2P (peer-to-peer) sessions
Get active session data
requires authentication
Returns P2P sessions with status "waiting_for_decision" or "in_progress".
Example request:
curl --request GET \
--get "http://localhost:8000/api/p2p/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/p2p/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"amputee_id": null,
"device_id": null,
"clinician_id": null,
"amputee_uuid": "4a4da2a5-0148-3666-8124-dc6ccd6acab8",
"clinician_uuid": "a4a3cc0d-2e4d-3bf6-b282-6d3f6cd82182",
"token": "3DDFQALNHGD6L8WBMQUHQ4HVPZCWZ3Q9GWEQ5ALTPKDQAP78U97MC33KTLVR8RL6",
"status": "waiting_for_decision",
"created_at": "2026-09-22T11:25:19.000000Z",
"updated_at": "2026-09-22T11:25:19.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view active P2P session",
"code": "P2P_SESSIONS:GET_ACTIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Session not found):
{
"message": "P2P session not found",
"code": "P2P_SESSIONS:GET_ACTIVE:SESSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
P2P session ID.
device_id
integer
Associated device ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
amputee_uuid
string
Amputee WebRTC UUID.
clinician_uuid
string
Clinician WebRTC UUID.
token
string
Session token.
status
string
Session status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
amputee
object
Patient user.
clinician
object
Clinician user.
Get session data
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/p2p/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/p2p/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 2,
"amputee_id": null,
"device_id": null,
"clinician_id": null,
"amputee_uuid": "4cef7dc4-5673-35df-8d33-42a8af20e721",
"clinician_uuid": "ca8c10d6-73f8-30a3-84b5-a05e5ee94237",
"token": "RPXWHR4XASHTJ6NFV42WSRSV77ZWPCVHBNNEWM7YACLU5NK2R6JQL62MAQY47BX6",
"status": "waiting_for_decision",
"created_at": "2026-09-22T11:25:19.000000Z",
"updated_at": "2026-09-22T11:25:19.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view P2P session",
"code": "P2P_SESSIONS:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Session not found):
{
"message": "P2P session not found",
"code": "P2P_SESSIONS:GET:SESSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
P2P session ID.
device_id
integer
Associated device ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
amputee_uuid
string
Amputee WebRTC UUID.
clinician_uuid
string
Clinician WebRTC UUID.
token
string
Session token.
status
string
Session status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
amputee
object
Patient user.
clinician
object
Clinician user.
Create new P2P session
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/p2p/create" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amputee_id\": 2,
\"device_id\": 5,
\"amputee_uuid\": \"3697c793-30b7-3ae3-a417-9fbcdf9d3d9e\",
\"clinician_uuid\": \"5eca013f-b879-30ad-8c92-380538540954\"
}"
const url = new URL(
"http://localhost:8000/api/p2p/create"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amputee_id": 2,
"device_id": 5,
"amputee_uuid": "3697c793-30b7-3ae3-a417-9fbcdf9d3d9e",
"clinician_uuid": "5eca013f-b879-30ad-8c92-380538540954"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"amputee_id": 123,
"device_id": null,
"clinician_id": 124,
"amputee_uuid": "2ea90aa4-03f9-389a-9c5d-70212b55c58c",
"clinician_uuid": "a1beb579-ab81-3f13-bdf3-b065338f50f5",
"token": "TQBBPLAHJM3SSKB2T8JJAM9DK58CBQDE6AL4KV7ZQS4RUDC4RJHFJD4XG8SQ96QJ",
"status": "waiting_for_decision",
"created_at": "2026-09-22T11:25:20.000000Z",
"updated_at": "2026-09-22T11:25:20.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create P2P session",
"code": "P2P_SESSIONS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Device not assigned to patient):
{
"message": "Device is not assigned to the patient",
"code": "P2P_SESSIONS:CREATE:DEVICE_NOT_ASSIGNED"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "P2P_SESSIONS:CREATE:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
P2P session ID.
device_id
integer
Associated device ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
amputee_uuid
string
Amputee WebRTC UUID.
clinician_uuid
string
Clinician WebRTC UUID.
token
string
Session token.
status
string
Session status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
amputee
object
Patient user.
clinician
object
Clinician user.
Update P2P session
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/p2p/1/update" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"status\": \"closed\"
}"
const url = new URL(
"http://localhost:8000/api/p2p/1/update"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"status": "closed"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 4,
"amputee_id": null,
"device_id": null,
"clinician_id": null,
"amputee_uuid": "5be0da2e-7b77-37cd-a2ab-0c9bc03ecc04",
"clinician_uuid": "4b67818d-49c2-3e54-9420-fd9a0dce7a77",
"token": "56S2AUAERXZTY8WVWDE4FYYBWK35LSB2QY95NJQ7ESKJGU3C6UBKYHY9Z7Z2FKSA",
"status": "waiting_for_decision",
"created_at": "2026-09-22T11:25:21.000000Z",
"updated_at": "2026-09-22T11:25:21.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update P2P session",
"code": "P2P_SESSIONS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Session not found):
{
"message": "P2P session not found",
"code": "P2P_SESSIONS:UPDATE:SESSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
P2P session ID.
device_id
integer
Associated device ID.
amputee_id
integer
Patient (amputee) user ID.
clinician_id
integer
Clinician user ID.
amputee_uuid
string
Amputee WebRTC UUID.
clinician_uuid
string
Clinician WebRTC UUID.
token
string
Session token.
status
string
Session status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
amputee
object
Patient user.
clinician
object
Clinician user.
Product features and toggles
API endpoints for product features and toggles management
Definitions:
- Product feature - part of application which can be considered as hardware compatible (with for example specific PCB version) or software compatible (with for example specific firmware version). Product features are used in versions compatibility matrix.
- Product toggle - part of application which can be enabled and disabled for current environment.
List product features
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/product/features" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/product/features"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"name": "maroon",
"slug": "voluptate-temporibus-eligendi-nemo",
"created_at": "2026-09-22T11:26:26.000000Z",
"updated_at": "2026-09-22T11:26:26.000000Z"
},
{
"id": 2,
"name": "silver",
"slug": "laboriosam-ab-nostrum-molestias-sint",
"created_at": "2026-09-22T11:26:26.000000Z",
"updated_at": "2026-09-22T11:26:26.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view product features and toggles",
"code": "PRODUCT_FEATURES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product feature ID.
name
string
Feature name.
slug
string
Feature slug (unique identifier).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create product feature
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/product/features" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote config\",
\"slug\": \"remote_config\"
}"
const url = new URL(
"http://localhost:8000/api/product/features"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote config",
"slug": "remote_config"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "gray",
"slug": "eos-quo-dicta-quibusdam-non-eos",
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_FEATURES:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product feature ID.
name
string
Feature name.
slug
string
Feature slug (unique identifier).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update product feature
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/product/features/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote config\",
\"slug\": \"remote_config\"
}"
const url = new URL(
"http://localhost:8000/api/product/features/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote config",
"slug": "remote_config"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"name": "navy",
"slug": "sunt-minima-similique-voluptatem-laudantium",
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_FEATURES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Product feature not found):
{
"message": "Product feature not found",
"code": "PRODUCT_FEATURES:UPDATE:FEATURE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product feature ID.
name
string
Feature name.
slug
string
Feature slug (unique identifier).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete product feature
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/product/features/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/product/features/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Product feature deleted",
"code": "PRODUCT_FEATURES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_FEATURES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, Product feature belongs to compatibility entries):
{
"message": "Cannot delete: product feature belongs to existing compatibility entries (1)",
"code": "PRODUCT_FEATURES:DELETE:HAS_COMPATIBILITY_ENTRIES"
}
Example response (404, Product feature not found):
{
"message": "Product feature not found",
"code": "PRODUCT_FEATURES:DELETE:FEATURE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List product toggles
requires authentication
This endpoint returns list of global toggles. For some users there could exist user toggle which overrides these settings.
Example request:
curl --request GET \
--get "http://localhost:8000/api/product/toggles?global=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/product/toggles"
);
const params = {
"global": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"name": "maroon",
"slug": "reprehenderit-exercitationem-consequatur-quisquam-voluptatibus-id",
"enabled": 1,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
},
{
"id": 2,
"name": "blue",
"slug": "animi-dolorem-ut-rerum-dolorum-fugit",
"enabled": 0,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view product features and toggles",
"code": "PRODUCT_TOGGLES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product toggle ID.
name
string
Toggle name.
slug
string
Toggle slug (unique identifier).
enabled
boolean
Whether the toggle is enabled globally.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create product toggle
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/product/toggles" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote config\",
\"slug\": \"remote_config\",
\"enabled\": true
}"
const url = new URL(
"http://localhost:8000/api/product/toggles"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote config",
"slug": "remote_config",
"enabled": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "green",
"slug": "commodi-quis-officiis-ut-dolorum-similique-et-non",
"enabled": 0,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_TOGGLES:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product toggle ID.
name
string
Toggle name.
slug
string
Toggle slug (unique identifier).
enabled
boolean
Whether the toggle is enabled globally.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update product toggle
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/product/toggles/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Remote config\",
\"slug\": \"remote_config\",
\"enabled\": true
}"
const url = new URL(
"http://localhost:8000/api/product/toggles/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Remote config",
"slug": "remote_config",
"enabled": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"name": "black",
"slug": "enim-est-rerum-ipsa-similique-omnis-laudantium",
"enabled": 0,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_TOGGLES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Product toggle not found):
{
"message": "Product toggle not found",
"code": "PRODUCT_TOGGLES:UPDATE:TOGGLE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Product toggle ID.
name
string
Toggle name.
slug
string
Toggle slug (unique identifier).
enabled
boolean
Whether the toggle is enabled globally.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete product toggle
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/product/toggles/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/product/toggles/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Product toggle deleted",
"code": "PRODUCT_TOGGLES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "PRODUCT_TOGGLES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Product toggle not found):
{
"message": "Product toggle not found",
"code": "PRODUCT_TOGGLES:DELETE:TOGGLE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List product FAQ
requires authentication
This endpoint returns list of product FAQ.
Example request:
curl --request GET \
--get "http://localhost:8000/api/product/faq" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/product/faq"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"question": "Vel repellat distinctio et quisquam. Autem ut odio veritatis et ea. Molestiae voluptas inventore id dolores dicta quia. Consequuntur consequatur voluptatem nisi inventore quae odio nobis.",
"answer": "Cupiditate assumenda enim eum blanditiis nam nisi quasi. Ipsa libero quam delectus dignissimos. Dolores atque debitis id harum natus repellendus. Inventore eaque ut omnis.",
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
},
{
"id": 2,
"question": "Temporibus laborum quia possimus ullam nisi distinctio sint rem. Rerum culpa ex consequatur fugiat voluptatem reiciendis porro. Enim minima dolor omnis officia officiis nihil.",
"answer": "Sunt quia sed deleniti. Molestias alias quia velit error consequatur provident expedita voluptatem. Libero est sequi molestiae soluta.",
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view product features and toggles",
"code": "FAQ:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
FAQ entry ID.
question
string
FAQ question.
answer
string
FAQ answer.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
List user toggles
requires authentication
This endpoint returns list of user toggles with their global toggles.
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1/toggles" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/toggles"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"toggle_id": 6,
"user_id": 256,
"enabled": 1,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z",
"toggle": {
"id": 6,
"name": "navy",
"slug": "nobis-nostrum-delectus-ut-corporis",
"enabled": 0,
"created_at": "2026-09-22T11:26:27.000000Z",
"updated_at": "2026-09-22T11:26:27.000000Z"
}
},
{
"id": 2,
"toggle_id": 8,
"user_id": 257,
"enabled": 1,
"created_at": "2026-09-22T11:26:28.000000Z",
"updated_at": "2026-09-22T11:26:28.000000Z",
"toggle": {
"id": 8,
"name": "lime",
"slug": "delectus-ea-vero-placeat-blanditiis-esse-totam-quibusdam",
"enabled": 1,
"created_at": "2026-09-22T11:26:28.000000Z",
"updated_at": "2026-09-22T11:26:28.000000Z"
}
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view product features and toggles",
"code": "USER_TOGGLES:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USER_TOGGLES:LIST:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User product toggle ID.
toggle_id
integer
Associated product toggle ID.
user_id
integer
Associated user ID.
enabled
boolean
Whether the toggle is enabled for this user.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
toggle
object
Associated product toggle.
Create user toggle
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/toggles" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"toggle_id\": 1,
\"enabled\": true
}"
const url = new URL(
"http://localhost:8000/api/user/1/toggles"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"toggle_id": 1,
"enabled": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"toggle_id": 9,
"user_id": 258,
"enabled": 1,
"created_at": "2026-09-22T11:26:28.000000Z",
"updated_at": "2026-09-22T11:26:28.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "USER_TOGGLES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Cannot create user toggles for SuperAdmin):
{
"message": "Cannot create user toggles for SuperAdmin",
"code": "USER_TOGGLES:CREATE:CANNOT_CREATE_FOR_SUPER_ADMIN"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USER_TOGGLES:CREATE:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User product toggle ID.
toggle_id
integer
Associated product toggle ID.
user_id
integer
Associated user ID.
enabled
boolean
Whether the toggle is enabled for this user.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
toggle
object
Associated product toggle.
Update user toggle
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/user/1/toggles/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"enabled\": true
}"
const url = new URL(
"http://localhost:8000/api/user/1/toggles/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"enabled": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"toggle_id": 10,
"user_id": 259,
"enabled": 0,
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "USER_TOGGLES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USER_TOGGLES:UPDATE:USER_NOT_FOUND"
}
Example response (404, User toggle not found):
{
"message": "User toggle not found",
"code": "USER_TOGGLES:UPDATE:TOGGLE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User product toggle ID.
toggle_id
integer
Associated product toggle ID.
user_id
integer
Associated user ID.
enabled
boolean
Whether the toggle is enabled for this user.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
toggle
object
Associated product toggle.
Delete user toggle
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/user/1/toggles/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/toggles/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "User toggle deleted",
"code": "USER_TOGGLES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage product features and toggles",
"code": "USER_TOGGLES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USER_TOGGLES:DELETE:USER_NOT_FOUND"
}
Example response (404, User toggle not found):
{
"message": "User toggle not found",
"code": "USER_TOGGLES:DELETE:TOGGLE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Release notes
Endpoints related to release notes
List release notes
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/release-notes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"status\": \"minus\"
}"
const url = new URL(
"http://localhost:8000/api/release-notes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"status": "minus"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"sync_uuid": "66cc568c-a2c7-4aa6-a676-43c7d3ddba8d",
"title": "Voluptas sed in sunt cumque.",
"body": "<p>Et fugit molestiae inventore recusandae dolore. Eum neque incidunt quos excepturi consequuntur nihil amet possimus. Voluptatem sed necessitatibus veniam ex et sunt nostrum reprehenderit.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
},
{
"id": 2,
"sync_uuid": "413a9932-32c2-498a-a4ec-166891343329",
"title": "Quia ratione qui eveniet.",
"body": "<p>Incidunt eos sint aut cupiditate. Sed provident saepe ea animi. Saepe et labore quia nam laudantium voluptas tenetur. Odio quasi et aut in minus similique nemo.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view release notes",
"code": "RELEASE_NOTES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create release note
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/release-notes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "title=New grip control available"\
--form "body=<p>We just shipped a new grip control.</p>"\
--form "sync_uuid=017f9e67-af39-3203-917f-e6a5c41e352b"\
--form "video=@/tmp/phpUBlEMC" const url = new URL(
"http://localhost:8000/api/release-notes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('title', 'New grip control available');
body.append('body', '<p>We just shipped a new grip control.</p>');
body.append('sync_uuid', '017f9e67-af39-3203-917f-e6a5c41e352b');
body.append('video', document.querySelector('input[name="video"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 3,
"sync_uuid": "dfb5d6e2-df85-4106-89b6-cc5829096cc3",
"title": "Accusamus sint ut.",
"body": "<p>Sed sequi vel quisquam fuga ut deleniti autem. Veniam ut at aut omnis nihil. Suscipit sit dolore architecto illo odio.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage release notes",
"code": "RELEASE_NOTES:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (500, Server error):
{
"message": "Server error: release note not created",
"code": "RELEASE_NOTES:CREATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update release note
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/release-notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "title=New grip control available"\
--form "body=<p>We just shipped a new grip control.</p>"\
--form "video=@/tmp/php0AuOBB" const url = new URL(
"http://localhost:8000/api/release-notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('title', 'New grip control available');
body.append('body', '<p>We just shipped a new grip control.</p>');
body.append('video', document.querySelector('input[name="video"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Example response (202):
{
"id": 4,
"sync_uuid": "6e9fecf8-a932-46c5-83df-13fb056bc1f9",
"title": "Placeat commodi dolor odit aperiam.",
"body": "<p>Molestias accusamus aut sed et est aut aliquid recusandae. Exercitationem reiciendis ea doloribus vel vero fuga eos soluta. Temporibus molestiae libero architecto. Sequi est iusto dolorem pariatur optio porro.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
Example response (403, Release note is not editable):
{
"message": "Release note is not editable",
"code": "RELEASE_NOTES:UPDATE:NOT_EDITABLE"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage release notes",
"code": "RELEASE_NOTES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release note not found):
{
"message": "Release note not found",
"code": "RELEASE_NOTES:UPDATE:NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: release note not updated",
"code": "RELEASE_NOTES:UPDATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete release note
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/release-notes/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Release note deleted",
"code": "RELEASE_NOTES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage release notes",
"code": "RELEASE_NOTES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release note not found):
{
"message": "Release note not found",
"code": "RELEASE_NOTES:DELETE:NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: release note not deleted",
"code": "RELEASE_NOTES:DELETE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Activate release note
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/release-notes/1/activate" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/1/activate"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 5,
"sync_uuid": "870b8894-cde7-4f8e-aa6c-4dbbafbb6a95",
"title": "Autem ab explicabo voluptatum modi.",
"body": "<p>Excepturi omnis in et omnis. Molestiae sed quidem ut ad. Officiis illo iure aliquam nostrum voluptas.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
Example response (403, Release note is already active):
{
"message": "Release note is already active",
"code": "RELEASE_NOTES:ACTIVATE:ALREADY_ACTIVE"
}
Example response (403, Translation is not ready yet):
{
"message": "Release note translation is not ready yet",
"code": "RELEASE_NOTES:ACTIVATE:TRANSLATION_NOT_READY"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage release notes",
"code": "RELEASE_NOTES:ACTIVATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release note not found):
{
"message": "Release note not found",
"code": "RELEASE_NOTES:ACTIVATE:NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: release note not activated",
"code": "RELEASE_NOTES:ACTIVATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Archive release note
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/release-notes/1/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/1/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 6,
"sync_uuid": "5062d208-bfe9-4a29-ac59-6598fc26bf46",
"title": "Sed dolorem consequuntur non magnam.",
"body": "<p>Temporibus assumenda asperiores et culpa aspernatur necessitatibus. Quibusdam magni consectetur reprehenderit provident consequatur voluptas qui. Pariatur voluptatibus accusantium et id aut id ut. Deleniti nisi fugit omnis.</p>",
"video": null,
"status": "draft",
"translation_status": "STARTED",
"activated_at": null,
"archived_at": null,
"created_by": null,
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage release notes",
"code": "RELEASE_NOTES:ARCHIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release note not found):
{
"message": "Release note not found",
"code": "RELEASE_NOTES:ARCHIVE:NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: release note not archived",
"code": "RELEASE_NOTES:ARCHIVE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get release notes status
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/release-notes/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (401):
Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
{
"message": "api.responses.general.unauthenticated",
"code": "GENERAL:UNAUTHENTICATED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view release notes",
"code": "RELEASE_NOTES:STATUS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Dismiss release note popup
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/release-notes/1/dismiss" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/1/dismiss"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Release note dismissed",
"code": "RELEASE_NOTES:DISMISS:DISMISSED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view release notes",
"code": "RELEASE_NOTES:DISMISS:INSUFFICIENT_PERMISSION"
}
Example response (404, Release note not found):
{
"message": "Release note not found",
"code": "RELEASE_NOTES:DISMISS:NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Mark release notes as seen
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/release-notes/mark-seen" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/release-notes/mark-seen"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200, OK):
{
"message": "Release notes marked as seen",
"code": "RELEASE_NOTES:MARK_SEEN:MARKED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view release notes",
"code": "RELEASE_NOTES:MARK_SEEN:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Releases
API endpoints for releases management
List releases
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/releases" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/releases"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"version_type": "App\\Models\\SoftwareVersion",
"version_id": 14,
"description": "Rerum veritatis quasi totam perspiciatis rerum. Voluptates aut est sed dignissimos ut aut maxime. Et laborum dolor alias sunt. Tempore saepe consequatur deserunt beatae et cupiditate.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z",
"version": {
"id": 14,
"name": "3.25.97",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
},
{
"id": 2,
"version_type": "App\\Models\\SoftwareVersion",
"version_id": 15,
"description": "Omnis repellat sit ea at sed nam. Nostrum vel harum accusantium ad. Atque enim accusantium sint consequuntur esse blanditiis. Praesentium nesciunt magnam eos et et doloremque tempore quisquam.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z",
"version": {
"id": 15,
"name": "1.13.69",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list releases",
"code": "RELEASES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Release ID.
version_type
string
Version model type (morph class name).
version_id
integer
Version model ID.
description
string
Release notes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
version
object
Associated version (software, firmware or PCB).
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get release
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/releases/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/releases/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 3,
"version_type": "App\\Models\\SoftwareVersion",
"version_id": 16,
"description": "Voluptatem distinctio accusantium voluptas id maxime. Omnis illum est explicabo dignissimos. Veniam neque veniam ab repudiandae ut est magnam.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z",
"version": {
"id": 16,
"name": "9.54.62",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view release",
"code": "RELEASES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Release not found):
{
"message": "Release not found",
"code": "RELEASES:GET:RELEASE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Release ID.
version_type
string
Version model type (morph class name).
version_id
integer
Version model ID.
description
string
Release notes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
version
object
Associated version (software, firmware or PCB).
Create release
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/releases" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"version_type\": \"SoftwareVersion\",
\"version_id\": 1,
\"description\": \"This version fixes minor bugs.\"
}"
const url = new URL(
"http://localhost:8000/api/releases"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"version_type": "SoftwareVersion",
"version_id": 1,
"description": "This version fixes minor bugs."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"version_type": "App\\Models\\SoftwareVersion",
"version_id": 17,
"description": "Occaecati reiciendis autem rerum quidem at. Ab pariatur esse aut dolorum ea rerum architecto. Perspiciatis unde libero animi in dolores deserunt ullam. Magni maxime molestiae eaque asperiores.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create release",
"code": "RELEASES:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Release ID.
version_type
string
Version model type (morph class name).
version_id
integer
Version model ID.
description
string
Release notes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
version
object
Associated version (software, firmware or PCB).
Update release
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/releases/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"version_type\": \"SoftwareVersion\",
\"version_id\": 1,
\"description\": \"This version fixes minor bugs.\"
}"
const url = new URL(
"http://localhost:8000/api/releases/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"version_type": "SoftwareVersion",
"version_id": 1,
"description": "This version fixes minor bugs."
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 5,
"version_type": "App\\Models\\SoftwareVersion",
"version_id": 18,
"description": "Sint quia eos itaque soluta velit et nobis. Sit est ut consequatur ab asperiores impedit ipsam eos. Odit qui est dolorem et tenetur. Reprehenderit inventore cum hic consequatur ea.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update release",
"code": "RELEASES:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release not found):
{
"message": "Release not found",
"code": "RELEASES:UPDATE:RELEASE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Release ID.
version_type
string
Version model type (morph class name).
version_id
integer
Version model ID.
description
string
Release notes.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
version
object
Associated version (software, firmware or PCB).
Delete release
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/releases/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/releases/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Version deleted",
"code": "RELEASES:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete release",
"code": "RELEASES:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Release not found):
{
"message": "Release not found",
"code": "RELEASES:DELETE:RELEASE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Search
API endpoints for search
Search
requires authentication
- users (by name and email)
- devices (by serial number)
Returned collection contains entries of type User or Device.
If the device has a patient assigned, this patient is included in the results as an entry of type User. If the device has no patient, the device is included in the results.
Users included in the results, but not found directly have "devices" relation filled in with the devices that match the search query.
Example request:
curl --request GET \
--get "http://localhost:8000/api/search?query=Tom" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"query\": \"nxsllsigqpyucjxdbjikhuyasseozxtsxrotbifrpdeevgpwsirjpjztgxohmodyjqgmyopxqzgovij\"
}"
const url = new URL(
"http://localhost:8000/api/search"
);
const params = {
"query": "Tom",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"query": "nxsllsigqpyucjxdbjikhuyasseozxtsxrotbifrpdeevgpwsirjpjztgxohmodyjqgmyopxqzgovij"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"type": "User",
"item": {
"id": 1,
"mrn": "MRN",
"name": "User name",
"email": "user@domain.com",
"language": "en",
"phone": "",
"phone_verified_at": null,
"address1": "",
"address2": "",
"postal_code": "",
"city": "",
"clinic_name": "Test Company",
"clinic_location": "Test Company Location",
"image": null,
"mfa_enabled": 0,
"mfa_method": "email",
"mfa_verified_to": null,
"created_by": null,
"active": 1,
"notifications_timezone": "Europe/Warsaw",
"notifications_at": "08:00:00",
"created_at": "2024-09-01T15:00:00.000000Z",
"updated_at": "2024-10-10T10:30:00.000000Z",
"invitation_status": "accepted",
"pivot": {
"assigned_user_id": 2,
"user_id": 1
},
"devices": [],
"roles": [
{
"id": 5,
"name": "Amputee",
"guard_name": "web",
"created_at": "2024-01-01T12:00:00.000000Z",
"updated_at": "2024-01-01T12:00:00.000000Z",
"pivot": {
"model_id": 1,
"role_id": 5,
"model_type": "App\\Models\\User"
}
}
]
}
},
{
"type": "Device",
"item": {
"id": 1,
"serial": "SERIAL-NUMBER",
"bluetooth_id": "BLUETOOTH_ID",
"model_id": 1,
"amputee_id": 1,
"firmware_version_id": 1,
"pcb_version_id": 1,
"active": 1,
"last_activity_at": "2024-11-11 12:00:00",
"created_at": "2024-08-30T15:00:00.000000Z",
"updated_at": "2024-09-01T16:00:00.000000Z",
"pivot": {
"user_id": 2,
"device_id": 1
}
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to search",
"code": "SEARCH:SEARCH:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Servicing
API endpoints for servicing
List of parts
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/servicing/parts" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/servicing/parts"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"device_model": null,
"name": "Visa",
"created_at": "2026-09-22T11:25:28.000000Z",
"updated_at": "2026-09-22T11:25:28.000000Z"
},
{
"id": 2,
"device_model": null,
"name": "MasterCard",
"created_at": "2026-09-22T11:25:29.000000Z",
"updated_at": "2026-09-22T11:25:29.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list service parts",
"code": "SERVICING:LIST_PARTS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Service part ID.
device_model
integer
Associated device model ID.
name
string
Part name.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Report service repair
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/servicing/repair" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "user_id=1"\
--form "device_id=1"\
--form "parts[][part_id]=1"\
--form "parts[][reason]=Mechanical issue"\
--form "files[]=@/tmp/phpexEq19" const url = new URL(
"http://localhost:8000/api/servicing/repair"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('user_id', '1');
body.append('device_id', '1');
body.append('parts[][part_id]', '1');
body.append('parts[][reason]', 'Mechanical issue');
body.append('files[]', document.querySelector('input[name="files[]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 1,
"user_id": 141,
"device_id": 128,
"created_at": "2026-09-22T11:25:29.000000Z",
"updated_at": "2026-09-22T11:25:29.000000Z",
"parts": [
{
"id": 1,
"repair_id": 1,
"part_id": 3,
"reason": "Molestiae eaque nobis deleniti animi velit eos. Sit nemo numquam vel nulla. Saepe et consequatur atque molestiae autem illo. Quia sit eius eius sint.",
"created_at": "2026-09-22T11:25:29.000000Z",
"updated_at": "2026-09-22T11:25:29.000000Z",
"part": {
"id": 3,
"device_model": null,
"name": "MasterCard",
"created_at": "2026-09-22T11:25:29.000000Z",
"updated_at": "2026-09-22T11:25:29.000000Z"
}
},
{
"id": 2,
"repair_id": 1,
"part_id": 4,
"reason": "Placeat rem magnam alias et ea assumenda. Sed sint aut quia. Quis consequuntur aut expedita maxime dolor. Facere adipisci tempora voluptatibus voluptatibus sunt amet deleniti.",
"created_at": "2026-09-22T11:25:31.000000Z",
"updated_at": "2026-09-22T11:25:31.000000Z",
"part": {
"id": 4,
"device_model": null,
"name": "MasterCard",
"created_at": "2026-09-22T11:25:30.000000Z",
"updated_at": "2026-09-22T11:25:30.000000Z"
}
},
{
"id": 3,
"repair_id": 1,
"part_id": 5,
"reason": "Soluta in et quis dicta velit qui quo. Quos architecto molestias voluptatibus non suscipit. Animi consequatur sed nisi est culpa quia.",
"created_at": "2026-09-22T11:25:31.000000Z",
"updated_at": "2026-09-22T11:25:31.000000Z",
"part": {
"id": 5,
"device_model": null,
"name": "American Express",
"created_at": "2026-09-22T11:25:31.000000Z",
"updated_at": "2026-09-22T11:25:31.000000Z"
}
}
],
"attachments": [
{
"id": 1,
"repair_id": 1,
"file": "/tmp/fakerXS2AsA",
"created_at": "2026-09-22T11:25:30.000000Z",
"updated_at": "2026-09-22T11:25:30.000000Z"
},
{
"id": 2,
"repair_id": 1,
"file": "/tmp/fakerlsnk7F",
"created_at": "2026-09-22T11:25:32.000000Z",
"updated_at": "2026-09-22T11:25:32.000000Z"
},
{
"id": 3,
"repair_id": 1,
"file": "/tmp/fakerS3rQ3O",
"created_at": "2026-09-22T11:25:32.000000Z",
"updated_at": "2026-09-22T11:25:32.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to report service repair",
"code": "SERVICING:REPORT_REPAIR:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Service repair ID.
user_id
integer
Associated user ID.
device_id
integer
Associated device ID.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
parts
object[]
Service parts included in the repair.
attachments
object[]
Repair attachments.
Settings
API endpoints for app settings
Get app version
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/settings/app-version" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/settings/app-version"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"version": "1.6.0"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get silent push timeout
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/settings/silent-push" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/settings/silent-push"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"timeout": "15"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get available languages
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/settings/languages" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/settings/languages"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"languages": [
"de",
"en",
"es",
"it",
"pl",
"ru",
"uk"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get mobile stores versions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/mobile/versions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/mobile/versions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"ios": "1.0",
"android": "1.0"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update app version
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/settings/app-version" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"version\": \"1.6.0\"
}"
const url = new URL(
"http://localhost:8000/api/settings/app-version"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"version": "1.6.0"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"version": "1.6.0"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update settings",
"code": "SETTINGS:UPDATE_APP_VERSION:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update silent push timeout
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/settings/silent-push" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"timeout\": 15
}"
const url = new URL(
"http://localhost:8000/api/settings/silent-push"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"timeout": 15
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"timeout": "15"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update settings",
"code": "SETTINGS:UPDATE_SILENT_PUSH:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update mobile stores versions
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/mobile/versions" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"ios\": \"1.1\",
\"android\": \"1.1\"
}"
const url = new URL(
"http://localhost:8000/api/mobile/versions"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"ios": "1.1",
"android": "1.1"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"ios": "1.0",
"android": "1.0"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update settings",
"code": "SETTINGS:UPDATE_MOBILE_STORES_VERSION:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get glove mode config
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/glove-mode-config" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/glove-mode-config"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"config": "{\"key\": \"value\"}"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view settings",
"code": "GLOVE_MODE_CONFIG:GET:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update glove mode config
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/glove-mode-config" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"config\": \"{\\\"key\\\": \\\"value\\\"}\"
}"
const url = new URL(
"http://localhost:8000/api/glove-mode-config"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"config": "{\"key\": \"value\"}"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"config": "{\"key\": \"value\"}"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update settings",
"code": "GLOVE_MODE_CONFIG:UPDATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Support Ticket
API endpoints for managing support tickets
Get tickets list
requires authentication
Possible extend options:
- sender - the user who created ticket
- recipient - the user who was ticket recipient
- device - the device assigned to ticket
- messages - message allocated to ticket
- messages.attachments - list of attachments assigned to message and ticket
- messages.sender - the user who wrote the message
Example request:
curl --request GET \
--get "http://localhost:8000/api/tickets?status=new&sender=1&recipient=1&device=1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tickets"
);
const params = {
"status": "new",
"sender": "1",
"recipient": "1",
"device": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 27,
"sender_id": 150,
"recipient_id": 151,
"device_id": 135,
"meeting_date": "2026-09-22 11:25:34",
"meeting_type": "online_meeting",
"contact_email": "mable.boehm@okon.com",
"status": "new",
"created_at": "2026-09-22T11:25:34.000000Z",
"updated_at": "2026-09-22T11:25:34.000000Z",
"sender": {
"id": 150,
"mrn": "66XPDCYT1790076333",
"name": "Gisselle Jenkins",
"email": "1790076333tmitchell@example.org",
"language": "en",
"phone": "+1-253-582-0578",
"phone_country": "BY",
"phone_verified_at": null,
"address1": "29971 Elissa Keys Apt. 888",
"address2": "Crystelport, LA 74070-2972",
"postal_code": "15649-6410",
"city": "O'Keefe-Johns",
"country": "LV",
"clinic_name": "North Bertram",
"clinic_location": "94520 Cormier Hollow Suite 871\nWest Monica, PA 94727",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:33.000000Z",
"updated_at": "2026-09-22T11:25:33.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 151,
"mrn": "3PC2AP3K1790076334",
"name": "Lavada Rempel",
"email": "1790076334orlando01@example.org",
"language": "en",
"phone": "1-815-863-4524",
"phone_country": "MG",
"phone_verified_at": null,
"address1": "47541 Schultz Centers",
"address2": "Greenville, TN 33487-1835",
"postal_code": "69606",
"city": "Lubowitz and Sons",
"country": "SK",
"clinic_name": "East Riverfort",
"clinic_location": "7802 Hessel Ville\nTraceyside, AR 80869-9981",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:34.000000Z",
"updated_at": "2026-09-22T11:25:34.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 135,
"serial": "1147a2b4-d14e-3786-85b8-08e0a538ed25",
"bluetooth_id": "89000720-5989-3fc7-af55-2c071f15a93a",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:25:34.000000Z",
"updated_at": "2026-09-22T11:25:34.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 15,
"ticket_id": 27,
"sender_id": 152,
"title": "Dr.",
"content": "Et eum rerum consectetur est ullam et.",
"is_read": false,
"created_at": "2026-09-22T11:25:36.000000Z",
"updated_at": "2026-09-22T11:25:36.000000Z"
}
]
},
{
"id": 35,
"sender_id": 164,
"recipient_id": 165,
"device_id": 136,
"meeting_date": "2026-09-22 11:25:41",
"meeting_type": "online_meeting",
"contact_email": "spollich@hickle.biz",
"status": "new",
"created_at": "2026-09-22T11:25:42.000000Z",
"updated_at": "2026-09-22T11:25:42.000000Z",
"sender": {
"id": 164,
"mrn": "4WAEWW6N1790076340",
"name": "Rae Bogan",
"email": "1790076340pritchie@example.net",
"language": "en",
"phone": "804.982.6354",
"phone_country": "PM",
"phone_verified_at": null,
"address1": "66989 Spinka Union Apt. 376",
"address2": "North Margaritaborough, MT 58491",
"postal_code": "66730",
"city": "Batz-Bahringer",
"country": "HU",
"clinic_name": "Casimirborough",
"clinic_location": "65496 Keely Haven\nSouth Royal, MT 09304",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:41.000000Z",
"updated_at": "2026-09-22T11:25:41.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 165,
"mrn": "KQYLA2QJ1790076341",
"name": "Dr. Madilyn Reynolds",
"email": "1790076341mack.hoeger@example.org",
"language": "en",
"phone": "360.259.0482",
"phone_country": "VC",
"phone_verified_at": null,
"address1": "964 Velda Fork Suite 231",
"address2": "East Alena, NM 10612-1737",
"postal_code": "05653",
"city": "Steuber, Schiller and Kris",
"country": "AT",
"clinic_name": "West Adrien",
"clinic_location": "33532 Alivia Port\nWebershire, MN 12333",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:41.000000Z",
"updated_at": "2026-09-22T11:25:41.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 136,
"serial": "562cff89-b2c3-39dd-8636-3bd176e47dac",
"bluetooth_id": "8dc4ae56-d1d6-3543-be78-7b2556407763",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:25:42.000000Z",
"updated_at": "2026-09-22T11:25:42.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 19,
"ticket_id": 35,
"sender_id": 166,
"title": "Ms.",
"content": "Soluta ex et molestias id praesentium quia sed ea.",
"is_read": false,
"created_at": "2026-09-22T11:25:43.000000Z",
"updated_at": "2026-09-22T11:25:43.000000Z"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list support tickets",
"code": "TICKETS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get tickets status
requires authentication
Counts tickets by their status
Example request:
curl --request GET \
--get "http://localhost:8000/api/tickets/status" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tickets/status"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"unread": 1
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list support tickets",
"code": "TICKETS:STATUS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get support ticket
requires authentication
Returns single support ticket in the response.
Example request:
curl --request GET \
--get "http://localhost:8000/api/ticket/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/ticket/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 43,
"sender_id": 178,
"recipient_id": 179,
"device_id": 137,
"meeting_date": "2026-09-22 11:25:49",
"meeting_type": "online_meeting",
"contact_email": "leda.herzog@beer.org",
"status": "new",
"created_at": "2026-09-22T11:25:49.000000Z",
"updated_at": "2026-09-22T11:25:49.000000Z",
"sender": {
"id": 178,
"mrn": "5WJCV3YX1790076348",
"name": "Eunice Schneider",
"email": "1790076348mcdermott.arturo@example.net",
"language": "en",
"phone": "+1.228.617.5910",
"phone_country": "PN",
"phone_verified_at": null,
"address1": "403 Chandler Squares",
"address2": "Port Earnestinebury, UT 21292",
"postal_code": "05166",
"city": "Stoltenberg PLC",
"country": "SE",
"clinic_name": "West Leilaburgh",
"clinic_location": "59060 Jocelyn Locks Suite 490\nSouth Jalyn, AL 27751",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:48.000000Z",
"updated_at": "2026-09-22T11:25:48.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 179,
"mrn": "66ZN7BJP1790076349",
"name": "Neha Zboncak",
"email": "1790076349hstark@example.com",
"language": "en",
"phone": "1-321-469-4978",
"phone_country": "TC",
"phone_verified_at": null,
"address1": "28115 Jess Shoals Suite 815",
"address2": "Leviberg, CO 64819",
"postal_code": "03928-4949",
"city": "Harris and Sons",
"country": "PT",
"clinic_name": "North Nola",
"clinic_location": "3490 Pagac Parks Suite 688\nNorth Talon, MT 19497",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:49.000000Z",
"updated_at": "2026-09-22T11:25:49.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 137,
"serial": "b9a24e07-19a3-3a1f-bce8-cda12c6b65fd",
"bluetooth_id": "e8be961f-8042-325b-ba4e-648a0ccd1ad7",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:25:49.000000Z",
"updated_at": "2026-09-22T11:25:49.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 23,
"ticket_id": 43,
"sender_id": 180,
"title": "Prof.",
"content": "Rerum quidem maiores sit.",
"is_read": false,
"created_at": "2026-09-22T11:25:51.000000Z",
"updated_at": "2026-09-22T11:25:51.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view support ticket",
"code": "TICKETS:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:GET:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Get support ticket history
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/ticket/1/history" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/ticket/1/history"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"ticket_id": 51,
"author_id": 193,
"action": "harum",
"reason": "Non qui sed porro dolores natus qui.",
"created_at": "2026-09-22T11:25:56.000000Z",
"updated_at": "2026-09-22T11:25:56.000000Z"
},
{
"id": 2,
"ticket_id": 52,
"author_id": 195,
"action": "voluptates",
"reason": "Facilis fugiat ullam et atque aut possimus dolores.",
"created_at": "2026-09-22T11:25:57.000000Z",
"updated_at": "2026-09-22T11:25:57.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view support ticket",
"code": "TICKETS:HISTORY:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:HISTORY:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
History entry ID.
ticket_id
integer
Associated support ticket ID.
author_id
integer
ID of the user who made this change.
action
string
Action performed.
reason
string
Reason for the action.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who made this change.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get support ticket available filters
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/tickets/available-filters" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tickets/available-filters"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"clinicians": [
{
"id": 95,
"mrn": null,
"name": "Name",
"email": "email",
"region": "us",
"language": "pl",
"phone": "+48-555555555",
"phone_verified_at": null,
"address1": "Address",
"address2": "Address 2",
"postal_code": "",
"city": "",
"clinic_name": "Name",
"clinic_location": "Name",
"image": "https://aether-dev-bucket.s3.amazonaws.com/users/LDueuv1uG218G7owaiLAaWRkpaGxjB0jEFwzZsT1.png",
"mfa_enabled": 0,
"mfa_method": "sms",
"mfa_verified_to": null,
"location_id": 2,
"created_by": 1,
"active": 1,
"notifications_timezone": "America/Adak",
"notifications_at": null,
"created_at": "2022-07-19T14:43:37.000000Z",
"updated_at": "2024-09-27T05:52:51.000000Z",
"invitation_status": "expired",
"roles": [
{
"id": 2,
"name": "Clinician",
"guard_name": "web",
"created_at": "2022-03-21T17:15:47.000000Z",
"updated_at": "2022-03-21T17:15:47.000000Z",
"pivot": {
"model_id": 95,
"role_id": 2,
"model_type": "App\\Models\\User"
}
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create support ticket",
"code": "TICKETS:AVAILABLE_FILTERS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create new support ticket
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/tickets" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "recipient=1"\
--form "device=1"\
--form "meeting_type=online_meeting"\
--form "meeting_date=2026-09-22 11:25:57"\
--form "contact_email=olindgren@hotmail.com"\
--form "message[content]=Qui voluptas commodi possimus."\
--form "message[title]=Non quia voluptatem animi."\
--form "message[attachments][]=@/tmp/phpapLb1P" const url = new URL(
"http://localhost:8000/api/tickets"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('recipient', '1');
body.append('device', '1');
body.append('meeting_type', 'online_meeting');
body.append('meeting_date', '2026-09-22 11:25:57');
body.append('contact_email', 'olindgren@hotmail.com');
body.append('message[content]', 'Qui voluptas commodi possimus.');
body.append('message[title]', 'Non quia voluptatem animi.');
body.append('message[attachments][]', document.querySelector('input[name="message[attachments][]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 53,
"sender_id": 196,
"recipient_id": 197,
"device_id": 138,
"meeting_date": "2026-09-22 11:25:58",
"meeting_type": "online_meeting",
"contact_email": "reagan.hodkiewicz@wuckert.com",
"status": "new",
"created_at": "2026-09-22T11:25:58.000000Z",
"updated_at": "2026-09-22T11:25:58.000000Z",
"sender": {
"id": 196,
"mrn": "ABJMP3FQ1790076357",
"name": "Dr. Jules Cummings Jr.",
"email": "1790076357jocelyn.jones@example.com",
"language": "en",
"phone": "1-347-877-9222",
"phone_country": "MW",
"phone_verified_at": null,
"address1": "3472 Alexzander Drive",
"address2": "East Trechester, VT 89665-1690",
"postal_code": "00409-2715",
"city": "Mills, Ziemann and Carroll",
"country": "MT",
"clinic_name": "Port Aidanstad",
"clinic_location": "10320 Reina Mountain Suite 315\nGaylordborough, ND 16825-0832",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:58.000000Z",
"updated_at": "2026-09-22T11:25:58.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 197,
"mrn": "UPFQ7C5L1790076358",
"name": "Arden Torp",
"email": "1790076358melissa.roberts@example.net",
"language": "en",
"phone": "1-561-730-1994",
"phone_country": "CC",
"phone_verified_at": null,
"address1": "136 Jailyn Summit Apt. 097",
"address2": "Toymouth, MT 61837-3615",
"postal_code": "29817",
"city": "Gusikowski Inc",
"country": "LT",
"clinic_name": "Euniceton",
"clinic_location": "7986 Efrain Roads\nSouth Manleyfort, VT 17942-4211",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:25:58.000000Z",
"updated_at": "2026-09-22T11:25:58.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 138,
"serial": "b7deada2-6e24-3434-a4b6-0a8890d02d1a",
"bluetooth_id": "088c036a-39ee-3bc2-bd13-a6830dabd5c0",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:25:58.000000Z",
"updated_at": "2026-09-22T11:25:58.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 27,
"ticket_id": 53,
"sender_id": 198,
"title": "Prof.",
"content": "Ipsa pariatur quod sint laudantium repellat.",
"is_read": false,
"created_at": "2026-09-22T11:26:00.000000Z",
"updated_at": "2026-09-22T11:26:00.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create support ticket",
"code": "TICKETS:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Close support ticket
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/ticket/1/close" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/ticket/1/close"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
{
"id": 61,
"sender_id": 210,
"recipient_id": 211,
"device_id": 139,
"meeting_date": "2026-09-22 11:26:05",
"meeting_type": "online_meeting",
"contact_email": "jast.favian@yahoo.com",
"status": "new",
"created_at": "2026-09-22T11:26:05.000000Z",
"updated_at": "2026-09-22T11:26:05.000000Z",
"sender": {
"id": 210,
"mrn": "6LSJ8T2L1790076364",
"name": "Keara Shanahan",
"email": "1790076364alang@example.org",
"language": "en",
"phone": "947.938.2352",
"phone_country": "GU",
"phone_verified_at": null,
"address1": "44392 Arvilla Flats",
"address2": "Tillmanburgh, MT 21777-1769",
"postal_code": "31814",
"city": "Dooley-Hackett",
"country": "CZ",
"clinic_name": "Beckerstad",
"clinic_location": "744 Ullrich Crossing\nEast Mozell, MS 35928",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:04.000000Z",
"updated_at": "2026-09-22T11:26:04.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 211,
"mrn": "ZXFRQ7WL1790076365",
"name": "Icie Maggio",
"email": "1790076365abbigail.jakubowski@example.org",
"language": "en",
"phone": "626.759.5686",
"phone_country": "IL",
"phone_verified_at": null,
"address1": "722 Ziemann Freeway",
"address2": "Lake Sherwoodtown, CT 20241",
"postal_code": "63451",
"city": "Kerluke-Cruickshank",
"country": "SK",
"clinic_name": "Elzaburgh",
"clinic_location": "117 Guy Meadow\nWisokyborough, WV 62962",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:05.000000Z",
"updated_at": "2026-09-22T11:26:05.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 139,
"serial": "913b6d7c-1983-3e07-a611-667eb075bf42",
"bluetooth_id": "bdb2a5dc-3b9a-34c2-b739-47bdd6215a15",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:05.000000Z",
"updated_at": "2026-09-22T11:26:05.000000Z",
"first_config_change_at": null
},
"messages": []
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to close support ticket",
"code": "TICKETS:CLOSE:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:CLOSE:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Reopen support ticket
requires authentication
Patient (Amputee) role can reopen only non-config tickets.
For config tickets patients will get "Insufficient permission" response.
For patients role reason field is required.
Example request:
curl --request POST \
"http://localhost:8000/api/ticket/1/reopen" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"reason\": \"Something is still not working\"
}"
const url = new URL(
"http://localhost:8000/api/ticket/1/reopen"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"reason": "Something is still not working"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 3,
"ticket_id": 62,
"author_id": 213,
"action": "est",
"reason": "Facere totam distinctio dolorem recusandae.",
"created_at": "2026-09-22T11:26:06.000000Z",
"updated_at": "2026-09-22T11:26:06.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to reopen support ticket",
"code": "TICKETS:REOPEN:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:REOPEN:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
History entry ID.
ticket_id
integer
Associated support ticket ID.
author_id
integer
ID of the user who made this change.
action
string
Action performed.
reason
string
Reason for the action.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
author
object
User who made this change.
Create new support ticket message
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/ticket/1/messages" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "title=Soluta expedita consequatur excepturi."\
--form "content=Et iusto ab et excepturi architecto perspiciatis."\
--form "attachments[]=@/tmp/phpY3LzlC" const url = new URL(
"http://localhost:8000/api/ticket/1/messages"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('title', 'Soluta expedita consequatur excepturi.');
body.append('content', 'Et iusto ab et excepturi architecto perspiciatis.');
body.append('attachments[]', document.querySelector('input[name="attachments[]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 63,
"sender_id": 214,
"recipient_id": 215,
"device_id": 140,
"meeting_date": "2026-09-22 11:26:07",
"meeting_type": "online_meeting",
"contact_email": "tillman.jaron@wuckert.com",
"status": "new",
"created_at": "2026-09-22T11:26:07.000000Z",
"updated_at": "2026-09-22T11:26:07.000000Z",
"sender": {
"id": 214,
"mrn": "L3GKECB91790076366",
"name": "Madelynn Kris",
"email": "1790076366leonie62@example.org",
"language": "en",
"phone": "+1 (337) 796-5156",
"phone_country": "AF",
"phone_verified_at": null,
"address1": "306 Ludie Place Apt. 937",
"address2": "Bradtkefurt, NM 36047",
"postal_code": "08004-5813",
"city": "Stehr, Von and Cassin",
"country": "UA",
"clinic_name": "South Eliseborough",
"clinic_location": "85639 Malvina Summit\nSouth Agustina, FL 63920",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:06.000000Z",
"updated_at": "2026-09-22T11:26:06.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 215,
"mrn": "WKV85UUC1790076367",
"name": "Era Cummings PhD",
"email": "1790076367littel.silas@example.org",
"language": "en",
"phone": "1-989-689-6973",
"phone_country": "KI",
"phone_verified_at": null,
"address1": "9465 Claire Flats Apt. 931",
"address2": "New Douglasshire, NY 55754",
"postal_code": "48298-5273",
"city": "Moore, Wunsch and Wiza",
"country": "US",
"clinic_name": "West Twila",
"clinic_location": "42207 Crystal Port\nLake Judsonberg, WV 00118-6525",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:07.000000Z",
"updated_at": "2026-09-22T11:26:07.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 140,
"serial": "46987a8a-c97e-3d95-a980-dd9fb807da0e",
"bluetooth_id": "cfd3134b-2812-32d4-8519-5a70b77a8ba5",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:07.000000Z",
"updated_at": "2026-09-22T11:26:07.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 31,
"ticket_id": 63,
"sender_id": 216,
"title": "Dr.",
"content": "Eius dolores rerum est vero libero.",
"is_read": false,
"created_at": "2026-09-22T11:26:09.000000Z",
"updated_at": "2026-09-22T11:26:09.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create support ticket",
"code": "TICKETS:CREATE_MESSAGE:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:CREATE_MESSAGE:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Mark all messages as read
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/ticket/1/read" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/ticket/1/read"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
{
"id": 71,
"sender_id": 228,
"recipient_id": 229,
"device_id": 141,
"meeting_date": "2026-09-22 11:26:14",
"meeting_type": "online_meeting",
"contact_email": "vsatterfield@gmail.com",
"status": "new",
"created_at": "2026-09-22T11:26:14.000000Z",
"updated_at": "2026-09-22T11:26:14.000000Z",
"sender": {
"id": 228,
"mrn": "UBH5873Q1790076373",
"name": "Jerry Farrell",
"email": "1790076373ymertz@example.net",
"language": "en",
"phone": "(678) 729-1293",
"phone_country": "SM",
"phone_verified_at": null,
"address1": "5255 Brigitte Isle",
"address2": "Nicholasville, UT 85544",
"postal_code": "69736-9343",
"city": "Swaniawski-Weissnat",
"country": "EE",
"clinic_name": "North Gerson",
"clinic_location": "4697 Astrid Fields Suite 180\nPort Unaville, VA 28347",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:13.000000Z",
"updated_at": "2026-09-22T11:26:13.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 229,
"mrn": "4A67W4ZS1790076374",
"name": "Bobby Goodwin IV",
"email": "1790076374kaylee.herzog@example.org",
"language": "en",
"phone": "907.904.1949",
"phone_country": "KW",
"phone_verified_at": null,
"address1": "84516 Oren Mission",
"address2": "West Efren, GA 62454",
"postal_code": "07594",
"city": "Heidenreich Group",
"country": "SK",
"clinic_name": "Camillahaven",
"clinic_location": "72340 Jan Mills\nElenoraport, HI 46893",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:14.000000Z",
"updated_at": "2026-09-22T11:26:14.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 141,
"serial": "70ca378d-4915-3fcf-8d6d-ff03b55199d1",
"bluetooth_id": "23fff4fe-6b15-3a3c-8b44-abc5d8c3e080",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:14.000000Z",
"updated_at": "2026-09-22T11:26:14.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 35,
"ticket_id": 71,
"sender_id": 230,
"title": "Mr.",
"content": "Eligendi dolor omnis aut rerum nemo quae tempora.",
"is_read": false,
"created_at": "2026-09-22T11:26:16.000000Z",
"updated_at": "2026-09-22T11:26:16.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to read message",
"code": "TICKETS:READ_ALL:INSUFFICIENT_PERMISSION"
}
Example response (404, Support ticket not found):
{
"message": "Support ticket not found",
"code": "TICKETS:READ_ALL:TICKET_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Mark single message as read
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/ticket/1/read/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/ticket/1/read/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
{
"id": 79,
"sender_id": 242,
"recipient_id": 243,
"device_id": 142,
"meeting_date": "2026-09-22 11:26:20",
"meeting_type": "online_meeting",
"contact_email": "lakin.antwan@hotmail.com",
"status": "new",
"created_at": "2026-09-22T11:26:21.000000Z",
"updated_at": "2026-09-22T11:26:21.000000Z",
"sender": {
"id": 242,
"mrn": "2DY2JDZC1790076380",
"name": "Mireille Kris",
"email": "1790076380yundt.henderson@example.com",
"language": "en",
"phone": "+1 (386) 236-2375",
"phone_country": "MC",
"phone_verified_at": null,
"address1": "194 Hammes Landing",
"address2": "New Krista, MD 64371-5953",
"postal_code": "19213-2261",
"city": "Mueller-Conroy",
"country": "PT",
"clinic_name": "Lake Pietroville",
"clinic_location": "51818 Thompson Walks\nKiehnview, ID 72716-3088",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:20.000000Z",
"updated_at": "2026-09-22T11:26:20.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"recipient": {
"id": 243,
"mrn": "YWFB7DTQ1790076380",
"name": "Major Batz",
"email": "1790076380lehner.ernie@example.com",
"language": "en",
"phone": "+17166472861",
"phone_country": "NG",
"phone_verified_at": null,
"address1": "416 Emard Loaf",
"address2": "West Gwenport, NE 61006-8106",
"postal_code": "64377",
"city": "Sporer, Cartwright and Barrows",
"country": "EE",
"clinic_name": "Susieville",
"clinic_location": "3490 Hessel Causeway\nWisozkberg, CO 53735",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:26:20.000000Z",
"updated_at": "2026-09-22T11:26:20.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": []
},
"device": {
"id": 142,
"serial": "200c959d-2012-30bf-ba97-29cfaba96b2c",
"bluetooth_id": "ce5d1d62-e337-36c5-b1e4-8b9639b9fedf",
"company_id": null,
"model_id": null,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:26:21.000000Z",
"updated_at": "2026-09-22T11:26:21.000000Z",
"first_config_change_at": null
},
"messages": [
{
"id": 39,
"ticket_id": 79,
"sender_id": 244,
"title": "Dr.",
"content": "Animi aspernatur est rerum soluta.",
"is_read": false,
"created_at": "2026-09-22T11:26:22.000000Z",
"updated_at": "2026-09-22T11:26:22.000000Z"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to read message",
"code": "TICKETS:READ_MESSAGE:INSUFFICIENT_PERMISSION"
}
Example response (404, Message not found):
{
"message": "Message not found",
"code": "TICKETS:READ_MESSAGE:MESSAGE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Support ticket ID.
sender_id
integer
ID of the user who created the ticket.
recipient_id
integer
ID of the recipient user.
device_id
integer
Associated device ID.
meeting_date
string
Scheduled meeting date.
meeting_type
string
Meeting type.
Must be one of:onlinein-person
contact_email
string
Contact email address.
status
string
Ticket status.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
sender
object
User who created the ticket.
recipient
object
Recipient user.
device
object
Associated device.
messages
object[]
Ticket messages.
Tooltips
API endpoints for managing tooltips
List tooltips
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/tooltips" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tooltips"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"name": "Prof. Jalen Baumbach",
"type": "video",
"language": "os",
"file": "0",
"created_by": 306,
"created_at": "2026-09-22T11:26:57.000000Z",
"updated_at": "2026-09-22T11:26:57.000000Z",
"deleted_at": null
},
{
"id": 2,
"name": "Gregory Stracke",
"type": "video",
"language": "aa",
"file": "0",
"created_by": 307,
"created_at": "2026-09-22T11:26:57.000000Z",
"updated_at": "2026-09-22T11:26:57.000000Z",
"deleted_at": null
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list tooltips",
"code": "TOOLTIPS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Tooltip ID.
name
string
Tooltip identifier name.
type
string
Media type.
Must be one of:imagevideo
language
string
Language code (ISO 639-1).
file
string
File path or URL.
created_by
integer
ID of the user who created the tooltip.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
List archived tooltips
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/tooltips/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tooltips/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 3,
"name": "Dedrick Effertz",
"type": "video",
"language": "ng",
"file": "0",
"created_by": 308,
"created_at": "2026-09-22T11:26:58.000000Z",
"updated_at": "2026-09-22T11:26:58.000000Z",
"deleted_at": null
},
{
"id": 4,
"name": "Tatyana Rippin",
"type": "video",
"language": "ar",
"file": "0",
"created_by": 309,
"created_at": "2026-09-22T11:26:58.000000Z",
"updated_at": "2026-09-22T11:26:58.000000Z",
"deleted_at": null
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage tooltips",
"code": "TOOLTIPS:LIST_ARCHIVE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Tooltip ID.
name
string
Tooltip identifier name.
type
string
Media type.
Must be one of:imagevideo
language
string
Language code (ISO 639-1).
file
string
File path or URL.
created_by
integer
ID of the user who created the tooltip.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Create new tooltip
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/tooltips" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "name=Kris Plaza"\
--form "type=image"\
--form "language=pi"\
--form "file=@/tmp/phpMWfSKW" const url = new URL(
"http://localhost:8000/api/tooltips"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('name', 'Kris Plaza');
body.append('type', 'image');
body.append('language', 'pi');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 5,
"name": "Joanny Hamill",
"type": "image",
"language": "kj",
"file": "0",
"created_by": 310,
"created_at": "2026-09-22T11:26:59.000000Z",
"updated_at": "2026-09-22T11:26:59.000000Z",
"deleted_at": null
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage tooltips",
"code": "TOOLTIPS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (500, Server error):
{
"message": "Server error: tooltip not created",
"code": "TOOLTIPS:CREATE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Tooltip ID.
name
string
Tooltip identifier name.
type
string
Media type.
Must be one of:imagevideo
language
string
Language code (ISO 639-1).
file
string
File path or URL.
created_by
integer
ID of the user who created the tooltip.
deleted_at
string
Soft delete timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Archive tooltip
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/tooltips/1/archive" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tooltips/1/archive"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Tooltip archived",
"code": "TOOLTIPS:ARCHIVE:ARCHIVED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage tooltips",
"code": "TOOLTIPS:ARCHIVE:INSUFFICIENT_PERMISSION"
}
Example response (404, Tooltip not found):
{
"message": "Tooltip not found",
"code": "TOOLTIPS:ARCHIVE:TOOLTIP_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Restore archived tooltip
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/tooltips/1/restore" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/tooltips/1/restore"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Tooltip restored",
"code": "TOOLTIPS:RESTORE:RESTORED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage tooltips",
"code": "TOOLTIPS:RESTORE:INSUFFICIENT_PERMISSION"
}
Example response (404, Tooltip not found):
{
"message": "Tooltip not found",
"code": "TOOLTIPS:RESTORE:TOOLTIP_NOT_FOUND"
}
Example response (404, Tooltip is not archived):
{
"message": "Tooltip is not archived",
"code": "TOOLTIPS:RESTORE:TOOLTIP_NOT_ARCHIVED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Trainings
API endpoints for trainings
Get user trainings
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"user_id": 314,
"training_id": 2,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:01.000000Z",
"updated_at": "2026-09-22T11:27:01.000000Z",
"training": {
"id": 2,
"name": "nihil adipisci",
"created_at": "2026-09-22T11:27:01.000000Z",
"updated_at": "2026-09-22T11:27:01.000000Z"
}
},
{
"id": 2,
"user_id": 315,
"training_id": 4,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:01.000000Z",
"updated_at": "2026-09-22T11:27:01.000000Z",
"training": {
"id": 4,
"name": "magnam qui",
"created_at": "2026-09-22T11:27:01.000000Z",
"updated_at": "2026-09-22T11:27:01.000000Z"
}
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Get trainings for specific user (clinician access)
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 3,
"user_id": 316,
"training_id": 6,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:02.000000Z",
"updated_at": "2026-09-22T11:27:02.000000Z",
"training": {
"id": 6,
"name": "quia impedit",
"created_at": "2026-09-22T11:27:02.000000Z",
"updated_at": "2026-09-22T11:27:02.000000Z"
}
},
{
"id": 4,
"user_id": 317,
"training_id": 8,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:02.000000Z",
"updated_at": "2026-09-22T11:27:02.000000Z",
"training": {
"id": 8,
"name": "fugiat ut",
"created_at": "2026-09-22T11:27:02.000000Z",
"updated_at": "2026-09-22T11:27:02.000000Z"
}
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access patient training",
"code": "TRAININGS:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "TRAININGS:LIST:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Get user badges
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings/1/user-badges" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/1/user-badges"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"user_id": 318,
"badge_id": 1,
"created_at": "2026-09-22T11:27:02.000000Z",
"updated_at": "2026-09-22T11:27:02.000000Z"
},
{
"id": 2,
"user_id": 319,
"badge_id": 2,
"created_at": "2026-09-22T11:27:03.000000Z",
"updated_at": "2026-09-22T11:27:03.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:BADGES:INSUFFICIENT_PERMISSION"
}
Example response (403, User has no training started):
{
"message": "User has no training started",
"code": "TRAININGS:BADGES:NO_USER_TRAINING"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:BADGES:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User badge record ID.
user_id
integer
Associated user ID.
badge_id
integer
Associated badge ID.
created_at
string
Awarded timestamp.
updated_at
string
Last update timestamp.
Start user training
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/trainings/start/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/start/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 5,
"user_id": 320,
"training_id": 9,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:03.000000Z",
"updated_at": "2026-09-22T11:27:03.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:START:INSUFFICIENT_PERMISSION"
}
Example response (403, User training already started):
{
"message": "Cannot start: training already started",
"code": "TRAININGS:START:ALREADY_STARTED"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:START:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Update training
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/trainings/update/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"notifications_enabled\": false
}"
const url = new URL(
"http://localhost:8000/api/trainings/update/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"notifications_enabled": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 6,
"user_id": 321,
"training_id": 10,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:04.000000Z",
"updated_at": "2026-09-22T11:27:04.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (403, User has no training started):
{
"message": "User has no training started",
"code": "TRAININGS:UPDATE:NO_USER_TRAINING"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:UPDATE:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Get training progress
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings/progress/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/progress/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 7,
"user_id": 322,
"training_id": 11,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:04.000000Z",
"updated_at": "2026-09-22T11:27:04.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:PROGRESS:INSUFFICIENT_PERMISSION"
}
Example response (403, User has no training started):
{
"message": "User has no training started",
"code": "TRAININGS:PROGRESS:NO_USER_TRAINING"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:PROGRESS:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Mark training task done
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/trainings/1/day/2/task/3" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/1/day/2/task/3"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"id": 8,
"user_id": 323,
"training_id": 12,
"notifications_enabled": 1,
"created_at": "2026-09-22T11:27:05.000000Z",
"updated_at": "2026-09-22T11:27:05.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:MARK_DONE:INSUFFICIENT_PERMISSION"
}
Example response (403, User has no training started):
{
"message": "User has no training started",
"code": "TRAININGS:MARK_DONE:NO_USER_TRAINING"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:MARK_DONE:TRAINING_NOT_FOUND"
}
Example response (404, Training day not found):
{
"message": "Training day not found",
"code": "TRAININGS:MARK_DONE:TRAINING_DAY_NOT_FOUND"
}
Example response (404, Training task not found):
{
"message": "Training task not found",
"code": "TRAININGS:MARK_DONE:TRAINING_TASK_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User training ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
notifications_enabled
boolean
Whether notifications are enabled for this training.
streak
integer
Current training streak (days).
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
training
object
Training details.
Save training exercises attempts
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/trainings/1/day/2/task/3/attempts" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "exercises[][date_start]=1981-07-01 14:35:57"\
--form "exercises[][date_end]=1986-06-14 15:30:43"\
--form "exercises[][end_reason]=back"\
--form "exercises[][config][common][fingerStrength][]=1"\
--form "exercises[][config][common][gripPositions][_]=0"\
--form "exercises[][config][common][gripPositions][0][initial][]=84"\
--form "exercises[][config][common][gripPositions][0][limit][]=88"\
--form "exercises[][config][common][gripPositions][1][initial][]=39"\
--form "exercises[][config][common][gripPositions][1][limit][]=89"\
--form "exercises[][config][common][gripPositions][2][initial][]=41"\
--form "exercises[][config][common][gripPositions][2][limit][]=43"\
--form "exercises[][config][common][gripPositions][3][initial][]=23"\
--form "exercises[][config][common][gripPositions][3][limit][]=32"\
--form "exercises[][config][common][gripPositions][4][initial][]=56"\
--form "exercises[][config][common][gripPositions][4][limit][]=76"\
--form "exercises[][config][common][gripPositions][5][initial][]=48"\
--form "exercises[][config][common][gripPositions][5][limit][]=53"\
--form "exercises[][config][common][gripPositions][6][initial][]=13"\
--form "exercises[][config][common][gripPositions][6][limit][]=79"\
--form "exercises[][config][common][gripPositions][7][initial][]=26"\
--form "exercises[][config][common][gripPositions][7][limit][]=33"\
--form "exercises[][config][common][gripPositions][8][initial][]=32"\
--form "exercises[][config][common][gripPositions][8][limit][]=78"\
--form "exercises[][config][common][gripPositions][9][initial][]=46"\
--form "exercises[][config][common][gripPositions][9][limit][]=47"\
--form "exercises[][config][common][gripPositions][10][initial][]=10"\
--form "exercises[][config][common][gripPositions][10][limit][]=19"\
--form "exercises[][config][common][gripPositions][11][initial][]=68"\
--form "exercises[][config][common][gripPositions][11][limit][]=84"\
--form "exercises[][config][common][gripPositions][12][initial][]=57"\
--form "exercises[][config][common][gripPositions][12][limit][]=73"\
--form "exercises[][config][common][gripPositions][13][initial][]=51"\
--form "exercises[][config][common][gripPositions][13][limit][]=84"\
--form "exercises[][config][common][inputSite][]=0"\
--form "exercises[][config][modes][][id]=83"\
--form "exercises[][config][modes][][name]=Explicabo modi quia sed qui nulla culpa."\
--form "exercises[][config][modes][][slot]=0"\
--form "exercises[][config][modes][][config][autoGrasp][]=0"\
--form "exercises[][config][modes][][config][coContractionTimings][]=500"\
--form "exercises[][config][modes][][config][controlMode][]=1"\
--form "exercises[][config][modes][][config][emgGains][]=100"\
--form "exercises[][config][modes][][config][emgSpike][]=0"\
--form "exercises[][config][modes][][config][emgThresholds][]=30"\
--form "exercises[][config][modes][][config][gripPairsConfig][]=6"\
--form "exercises[][config][modes][][config][gripSequentialConfig][]=4"\
--form "exercises[][config][modes][][config][gripSwitchingMode][]=1"\
--form "exercises[][config][modes][][config][holdOpen][]=1500"\
--form "exercises[][config][modes][][config][pulseTimings][]=470"\
--form "exercises[][config][modes][][config][softGrip][]=1"\
--form "exercises[][config][modes][][config][speedControlStrategy][]=0"\
--form "exercises[][firmware_id]=3155"\
--form "exercises[][app_version]=1.25.26"\
--form "exercises[][attempts][][date_start]=1970-04-30 20:58:49"\
--form "exercises[][attempts][][date_end]=2017-08-19 13:36:05"\
--form "exercises[][attempts][][result]=failure"\
--form "exercises[][emg_file]=@/tmp/phpS9zkXW" const url = new URL(
"http://localhost:8000/api/trainings/1/day/2/task/3/attempts"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('exercises[][date_start]', '1981-07-01 14:35:57');
body.append('exercises[][date_end]', '1986-06-14 15:30:43');
body.append('exercises[][end_reason]', 'back');
body.append('exercises[][config][common][fingerStrength][]', '1');
body.append('exercises[][config][common][gripPositions][_]', '0');
body.append('exercises[][config][common][gripPositions][0][initial][]', '84');
body.append('exercises[][config][common][gripPositions][0][limit][]', '88');
body.append('exercises[][config][common][gripPositions][1][initial][]', '39');
body.append('exercises[][config][common][gripPositions][1][limit][]', '89');
body.append('exercises[][config][common][gripPositions][2][initial][]', '41');
body.append('exercises[][config][common][gripPositions][2][limit][]', '43');
body.append('exercises[][config][common][gripPositions][3][initial][]', '23');
body.append('exercises[][config][common][gripPositions][3][limit][]', '32');
body.append('exercises[][config][common][gripPositions][4][initial][]', '56');
body.append('exercises[][config][common][gripPositions][4][limit][]', '76');
body.append('exercises[][config][common][gripPositions][5][initial][]', '48');
body.append('exercises[][config][common][gripPositions][5][limit][]', '53');
body.append('exercises[][config][common][gripPositions][6][initial][]', '13');
body.append('exercises[][config][common][gripPositions][6][limit][]', '79');
body.append('exercises[][config][common][gripPositions][7][initial][]', '26');
body.append('exercises[][config][common][gripPositions][7][limit][]', '33');
body.append('exercises[][config][common][gripPositions][8][initial][]', '32');
body.append('exercises[][config][common][gripPositions][8][limit][]', '78');
body.append('exercises[][config][common][gripPositions][9][initial][]', '46');
body.append('exercises[][config][common][gripPositions][9][limit][]', '47');
body.append('exercises[][config][common][gripPositions][10][initial][]', '10');
body.append('exercises[][config][common][gripPositions][10][limit][]', '19');
body.append('exercises[][config][common][gripPositions][11][initial][]', '68');
body.append('exercises[][config][common][gripPositions][11][limit][]', '84');
body.append('exercises[][config][common][gripPositions][12][initial][]', '57');
body.append('exercises[][config][common][gripPositions][12][limit][]', '73');
body.append('exercises[][config][common][gripPositions][13][initial][]', '51');
body.append('exercises[][config][common][gripPositions][13][limit][]', '84');
body.append('exercises[][config][common][inputSite][]', '0');
body.append('exercises[][config][modes][][id]', '83');
body.append('exercises[][config][modes][][name]', 'Explicabo modi quia sed qui nulla culpa.');
body.append('exercises[][config][modes][][slot]', '0');
body.append('exercises[][config][modes][][config][autoGrasp][]', '0');
body.append('exercises[][config][modes][][config][coContractionTimings][]', '500');
body.append('exercises[][config][modes][][config][controlMode][]', '1');
body.append('exercises[][config][modes][][config][emgGains][]', '100');
body.append('exercises[][config][modes][][config][emgSpike][]', '0');
body.append('exercises[][config][modes][][config][emgThresholds][]', '30');
body.append('exercises[][config][modes][][config][gripPairsConfig][]', '6');
body.append('exercises[][config][modes][][config][gripSequentialConfig][]', '4');
body.append('exercises[][config][modes][][config][gripSwitchingMode][]', '1');
body.append('exercises[][config][modes][][config][holdOpen][]', '1500');
body.append('exercises[][config][modes][][config][pulseTimings][]', '470');
body.append('exercises[][config][modes][][config][softGrip][]', '1');
body.append('exercises[][config][modes][][config][speedControlStrategy][]', '0');
body.append('exercises[][firmware_id]', '3155');
body.append('exercises[][app_version]', '1.25.26');
body.append('exercises[][attempts][][date_start]', '1970-04-30 20:58:49');
body.append('exercises[][attempts][][date_end]', '2017-08-19 13:36:05');
body.append('exercises[][attempts][][result]', 'failure');
body.append('exercises[][emg_file]', document.querySelector('input[name="exercises[][emg_file]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"user_id": 324,
"training_task_id": 1,
"date_start": "2022-06-22 07:30:26",
"date_end": "1979-10-31 16:46:59",
"end_reason": "ticketCreated",
"config": "{\"common\":{\"fingerStrength\":[1,100],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[35,21,22,29,22],\"limit\":[53,46,54,64,68]},\"1\":{\"initial\":[38,57,56,1,41],\"limit\":[93,72,88,84,63]},\"2\":{\"initial\":[4,48,19,64,70],\"limit\":[54,68,28,73,91]},\"3\":{\"initial\":[65,72,33,1,53],\"limit\":[90,82,85,5,95]},\"4\":{\"initial\":[61,7,35,31,43],\"limit\":[87,46,64,83,93]},\"5\":{\"initial\":[72,50,93,30,59],\"limit\":[92,71,95,59,76]},\"6\":{\"initial\":[37,8,42,36,43],\"limit\":[63,67,79,42,85]},\"7\":{\"initial\":[32,3,64,14,16],\"limit\":[49,51,95,69,87]},\"8\":{\"initial\":[27,44,29,26,5],\"limit\":[95,67,95,40,72]},\"9\":{\"initial\":[39,6,40,87,57],\"limit\":[68,20,82,92,85]},\"10\":{\"initial\":[70,31,17,21,1],\"limit\":[78,74,18,80,61]},\"11\":{\"initial\":[38,19,11,10,28],\"limit\":[75,88,75,13,61]},\"12\":{\"initial\":[17,55,4,12,32],\"limit\":[24,68,53,62,82]},\"13\":{\"initial\":[21,5,9,40,45],\"limit\":[81,50,51,62,79]}},\"inputSite\":[0]},\"modes\":[{\"id\":86,\"name\":\"Tempora in voluptatem est et.\",\"slot\":0,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[400,400],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[60,30,20,100,0,40,40,80,60,0],\"gripPairsConfig\":[4,8,10,3,2,6,12,7],\"gripSequentialConfig\":[255,5,9,255,13,4,12,3,1,255,6,11],\"gripSwitchingMode\":[1],\"holdOpen\":[1500,1500],\"pulseTimings\":[600,530,470,60],\"softGrip\":[0],\"speedControlStrategy\":[0]}},{\"id\":87,\"name\":\"Deserunt eligendi voluptatem et eum quo cupiditate esse.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,0],\"coContractionTimings\":[400,200],\"controlMode\":[1],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[20,30,10,10,50,90,20,30,80,60],\"gripPairsConfig\":[2,5,12,8,6,11,7,13],\"gripSequentialConfig\":[255,255,255,255,8,4,12,255,1,10,255,3],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,2500],\"pulseTimings\":[830,660,640,300],\"softGrip\":[0],\"speedControlStrategy\":[1]}},{\"id\":88,\"name\":\"Necessitatibus neque sunt sint occaecati eos aperiam et.\",\"slot\":2,\"config\":{\"autoGrasp\":[1,0],\"coContractionTimings\":[400,100],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[90,0,10,50,40,100,80,30,60,60],\"gripPairsConfig\":[13,11,8,9,4,3,5,6],\"gripSequentialConfig\":[2,3,13,12,6,10,255,9,5,4,1,255],\"gripSwitchingMode\":[3],\"holdOpen\":[2500,2500],\"pulseTimings\":[160,490,1000,460],\"softGrip\":[0],\"speedControlStrategy\":[0]}}]}",
"firmware_id": 24,
"app_version": "2.41.33",
"emg_file": "/tmp/fakerdMvk6q",
"created_at": "2026-09-22T11:27:05.000000Z",
"updated_at": "2026-09-22T11:27:05.000000Z",
"attempts": [
{
"id": 1,
"training_log_id": 1,
"date_start": "1990-10-28 18:58:54",
"date_end": "1999-12-07 08:15:51",
"result": "success",
"created_at": "2026-09-22T11:27:06.000000Z",
"updated_at": "2026-09-22T11:27:06.000000Z"
}
]
},
{
"id": 3,
"user_id": 326,
"training_task_id": 3,
"date_start": "1985-04-06 23:51:46",
"date_end": "1971-12-27 22:58:47",
"end_reason": "back",
"config": "{\"common\":{\"fingerStrength\":[1,400],\"gripPositions\":{\"_\":0,\"0\":{\"initial\":[13,59,8,37,25],\"limit\":[72,64,79,78,32]},\"1\":{\"initial\":[35,24,16,70,52],\"limit\":[91,40,55,89,58]},\"2\":{\"initial\":[47,45,54,6,48],\"limit\":[71,47,59,22,84]},\"3\":{\"initial\":[18,40,11,11,15],\"limit\":[20,58,12,12,33]},\"4\":{\"initial\":[14,46,17,5,44],\"limit\":[57,80,80,92,46]},\"5\":{\"initial\":[5,13,5,20,49],\"limit\":[50,63,40,36,51]},\"6\":{\"initial\":[44,81,13,52,15],\"limit\":[93,82,85,77,41]},\"7\":{\"initial\":[22,75,62,27,50],\"limit\":[52,90,69,77,82]},\"8\":{\"initial\":[19,22,3,5,22],\"limit\":[54,44,74,41,77]},\"9\":{\"initial\":[28,43,15,48,40],\"limit\":[62,76,58,94,51]},\"10\":{\"initial\":[69,5,56,62,18],\"limit\":[87,17,75,89,51]},\"11\":{\"initial\":[16,26,51,54,47],\"limit\":[42,29,69,89,88]},\"12\":{\"initial\":[35,46,34,4,19],\"limit\":[88,68,58,37,42]},\"13\":{\"initial\":[8,17,28,67,42],\"limit\":[89,46,33,84,61]}},\"inputSite\":[1]},\"modes\":[{\"id\":92,\"name\":\"Labore soluta illum voluptatum.\",\"slot\":0,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[300,300],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[40,90,10,30,80,50,100,20,80,40],\"gripPairsConfig\":[1,10,8,2,3,11,6,12],\"gripSequentialConfig\":[255,255,4,13,9,11,255,8,2,3,12,255],\"gripSwitchingMode\":[3],\"holdOpen\":[1500,2500],\"pulseTimings\":[710,360,490,790],\"softGrip\":[0],\"speedControlStrategy\":[1]}},{\"id\":93,\"name\":\"Dolores voluptatibus tenetur architecto rem ut quia voluptas.\",\"slot\":1,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[500,200],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[1,300],\"emgThresholds\":[60,40,90,70,0,10,10,40,90,70],\"gripPairsConfig\":[10,11,1,9,5,13,2,8],\"gripSequentialConfig\":[255,255,255,2,5,9,255,255,1,7,255,8],\"gripSwitchingMode\":[3],\"holdOpen\":[2000,2000],\"pulseTimings\":[730,450,400,120],\"softGrip\":[1],\"speedControlStrategy\":[1]}},{\"id\":94,\"name\":\"Dolorem laudantium itaque itaque dolorem.\",\"slot\":2,\"config\":{\"autoGrasp\":[0,100],\"coContractionTimings\":[400,100],\"controlMode\":[0],\"emgGains\":[100,100],\"emgSpike\":[0,300],\"emgThresholds\":[70,20,90,0,50,20,60,20,10,0],\"gripPairsConfig\":[12,13,9,6,8,5,1,11],\"gripSequentialConfig\":[6,255,9,255,11,5,1,7,3,12,8,4],\"gripSwitchingMode\":[2],\"holdOpen\":[2500,2500],\"pulseTimings\":[880,650,360,710],\"softGrip\":[0],\"speedControlStrategy\":[0]}}]}",
"firmware_id": 26,
"app_version": "4.9.72",
"emg_file": "/tmp/fakerl4VVTp",
"created_at": "2026-09-22T11:27:06.000000Z",
"updated_at": "2026-09-22T11:27:06.000000Z",
"attempts": [
{
"id": 2,
"training_log_id": 3,
"date_start": "1993-08-03 08:26:19",
"date_end": "2008-01-17 10:55:29",
"result": "failure",
"created_at": "2026-09-22T11:27:07.000000Z",
"updated_at": "2026-09-22T11:27:07.000000Z"
}
]
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:SAVE_ATTEMPTS:INSUFFICIENT_PERMISSION"
}
Example response (403, User has no training started):
{
"message": "User has no training started",
"code": "TRAININGS:SAVE_ATTEMPTS:NO_USER_TRAINING"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:SAVE_ATTEMPTS:TRAINING_NOT_FOUND"
}
Example response (404, Training day not found):
{
"message": "Training day not found",
"code": "TRAININGS:SAVE_ATTEMPTS:TRAINING_DAY_NOT_FOUND"
}
Example response (404, Training task not found):
{
"message": "Training task not found",
"code": "TRAININGS:SAVE_ATTEMPTS:TRAINING_TASK_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Training log entry ID.
user_id
integer
Associated user ID.
training_task_id
integer
Associated training task ID.
date_start
string
Session start datetime.
date_end
string
Session end datetime.
end_reason
string
Reason the session ended.
config
string
Device config snapshot at time of session.
firmware_id
integer
Firmware version ID used during session.
app_version
string
App version used during session.
emg_file
string
EMG data file URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
attempts
object[]
Training log attempts.
Get reward status
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings/1/reward" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/1/reward"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, Reward status):
{
"status": true
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:REWARD_STATUS:INSUFFICIENT_PERMISSION"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:REWARD_STATUS:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Save reward details
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/trainings/1/reward" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"physical\",
\"country\": \"IT\",
\"delivery\": \"ua_nova_poshta_branch_pickup\",
\"email\": \"daugherty.ophelia@hotmail.com\",
\"phone\": \"1-986-622-9916\",
\"full_name\": \"Wiley Dicki V\",
\"address1\": \"1321 Oceane Glen\",
\"address2\": \"Suite 452\",
\"city\": \"Lake Bradyborough\",
\"postal_code\": \"93515\",
\"state\": \"ITAQUE\",
\"parcel_locker_code\": \"59GYGMAT\",
\"pin_code\": \"559742\"
}"
const url = new URL(
"http://localhost:8000/api/trainings/1/reward"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "physical",
"country": "IT",
"delivery": "ua_nova_poshta_branch_pickup",
"email": "daugherty.ophelia@hotmail.com",
"phone": "1-986-622-9916",
"full_name": "Wiley Dicki V",
"address1": "1321 Oceane Glen",
"address2": "Suite 452",
"city": "Lake Bradyborough",
"postal_code": "93515",
"state": "ITAQUE",
"parcel_locker_code": "59GYGMAT",
"pin_code": "559742"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 1,
"user_id": 328,
"training_id": 21,
"type": "digital",
"country": "LV",
"delivery": "ua_nova_poshta_parcel_locker",
"email": "orodriguez@yundt.info",
"phone": "+1.732.558.7571",
"full_name": "Ottis Dickens",
"address1": "386 Jaylin Greens Apt. 466",
"address2": "77277 Doyle Route Suite 570\nNorth Anaismouth, NH 91069-9135",
"city": "North Kayborough",
"postal_code": "84245",
"state": "EX",
"parcel_locker_code": "H5N26MRV",
"pin_code": "129889",
"created_at": "2026-09-22T11:27:07.000000Z",
"updated_at": "2026-09-22T11:27:07.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user trainings",
"code": "TRAININGS:REWARD_SAVE:INSUFFICIENT_PERMISSION"
}
Example response (403, Reward details already exists):
{
"message": "Reward details already exists",
"code": "TRAININGS:REWARD_SAVE:ALREADY_EXISTS"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:REWARD_SAVE:TRAINING_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User reward ID.
user_id
integer
Associated user ID.
training_id
integer
Associated training ID.
type
string
Reward type.
Must be one of:digitalphysical
country
string
Delivery country code.
delivery
string
Delivery method.
Must be one of:home_deliveryparcel_locker
email
string
Recipient email.
phone
string
Recipient phone.
full_name
string
Recipient full name.
address1
string
Delivery address line 1.
address2
string
Delivery address line 2.
city
string
Delivery city.
postal_code
string
Delivery postal code.
state
string
Delivery state.
parcel_locker_code
string
Parcel locker code.
pin_code
string
PIN code for delivery.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Get user progress (clinician view)
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/trainings/progress/sed/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/trainings/progress/sed/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
[
{
"number": 1,
"key": "openClose",
"status": "completed",
"status_updated_at": "2026-02-04 11:00:00"
},
{
"number": 2,
"key": "holdOpen",
"status": "in_progress",
"status_updated_at": "2026-02-05 09:00:00"
},
{
"number": 3,
"key": "changeSignal",
"status": "not_started",
"status_updated_at": null
},
{
"number": 4,
"key": "thumbPositioning",
"status": "not_started",
"status_updated_at": null
},
{
"number": 5,
"key": "sequentialAndPairingMode",
"status": "not_started",
"status_updated_at": null
},
{
"number": 6,
"key": "fingerSpeedTraining",
"status": "not_started",
"status_updated_at": null
},
{
"number": 7,
"key": "freezeMode",
"status": "not_started",
"status_updated_at": null
},
{
"number": 8,
"key": "coreSkillsTest",
"status": "not_started",
"status_updated_at": null
},
{
"number": 9,
"key": "powerSoftGrip",
"status": "not_started",
"status_updated_at": null
},
{
"number": 10,
"key": "precisionGrip",
"status": "not_started",
"status_updated_at": null
},
{
"number": 11,
"key": "tripodGrip",
"status": "not_started",
"status_updated_at": null
},
{
"number": 12,
"key": "keyGrip",
"status": "not_started",
"status_updated_at": null
},
{
"number": 13,
"key": "gripSelection",
"status": "not_started",
"status_updated_at": null
},
{
"number": 14,
"key": "finalGripAndControlTest",
"status": "not_started",
"status_updated_at": null
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access patient training",
"code": "TRAININGS:PROGRESS_CLINICIAN:INSUFFICIENT_PERMISSION"
}
Example response (404, Training not found):
{
"message": "Training not found",
"code": "TRAININGS:PROGRESS_CLINICIAN:TRAINING_NOT_FOUND"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "TRAININGS:PROGRESS_CLINICIAN:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
User preferences
API endpoints for user preferences
List user preferences
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/preferences" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/preferences"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
{
"preference1": "value1",
"preference2": null,
"preference3": 1
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user preferences",
"code": "USERS_PREFERENCES:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get user preference
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/preferences/sidebar_enabled" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/preferences/sidebar_enabled"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 1,
"user_id": 329,
"name": "Cornsilk",
"value": "0",
"created_at": "2026-09-22T11:27:08.000000Z",
"updated_at": "2026-09-22T11:27:08.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user preferences",
"code": "USERS_PREFERENCES:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, User preference not found):
{
"message": "User preference not found",
"code": "USERS_PREFERENCES:GET:NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set user preference
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/preferences" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"sidebar_enabled\",
\"value\": \"1\"
}"
const url = new URL(
"http://localhost:8000/api/preferences"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "sidebar_enabled",
"value": "1"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 2,
"user_id": 330,
"name": "SpringGreen",
"value": "1",
"created_at": "2026-09-22T11:27:09.000000Z",
"updated_at": "2026-09-22T11:27:09.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to manage user preferences",
"code": "USERS_PREFERENCES:SET:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Users
API endpoints for user management
Get users list
requires authentication
Possible extend options:
- clinicians - users assigned to this user as clinicians (for Amputee role)
- patients - users assigned to this user as patients (for ClinicAdmin/Clinician/ClinicianSupport role)
- devices - products assigned to user (for Amputee role)
- devicesAsClinician - products assigned to user as clinician (for ClinicAdmin/Clinician/ClinicianSupport role)
- roles - user roles
- permissions - user permissions (for ClinicianSupport role)
Example request:
curl --request GET \
--get "http://localhost:8000/api/users?search=Tom&active=-1&clinician[]=17&roles=Clinician%2CAmputee&has_devices=1&user_toggles=goals%2Ctrainings" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/users"
);
const params = {
"search": "Tom",
"active": "-1",
"clinician[0]": "17",
"roles": "Clinician,Amputee",
"has_devices": "1",
"user_toggles": "goals,trainings",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 7,
"mrn": "XW9AGAT71790076260",
"name": "Mr. Orville Reichert III",
"email": "1790076260ucole@example.com",
"language": "en",
"phone": "1-985-413-2276",
"phone_country": "PT",
"phone_verified_at": null,
"address1": "658 Sherwood Squares Suite 997",
"address2": "Kayville, KY 00808",
"postal_code": "86322",
"city": "Kuphal-Kuhic",
"country": "SK",
"clinic_name": "New Jeramieberg",
"clinic_location": "112 Wyman Rest\nPort Jayceeview, ME 30147-4001",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:20.000000Z",
"updated_at": "2026-09-22T11:24:20.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"clinicians": [
{
"id": 8,
"mrn": "PXSWXKAM1790076261",
"name": "Giovani Herman",
"email": "1790076261zgerlach@example.com",
"language": "en",
"phone": "1-469-409-1033",
"phone_country": "US",
"phone_verified_at": null,
"address1": "55008 Buckridge Run",
"address2": "Lake Noemie, NE 84562",
"postal_code": "22458",
"city": "Ledner Group",
"country": "GB",
"clinic_name": "Kimberlybury",
"clinic_location": "4026 Veum Knolls Suite 750\nLake Betteborough, TX 36351-1272",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:21.000000Z",
"updated_at": "2026-09-22T11:24:21.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"pivot": {
"user_id": 7,
"assigned_user_id": 8
},
"roles": []
}
],
"devices": [
{
"id": 1,
"serial": "33602b72-08f5-3cf3-a722-e45cb8346acc",
"bluetooth_id": "dd5ba0ce-e0ac-3abe-8217-140fab8e013a",
"company_id": null,
"model_id": null,
"amputee_id": 7,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:21.000000Z",
"updated_at": "2026-09-22T11:24:21.000000Z",
"first_config_change_at": null
}
],
"roles": [
{
"id": 6,
"name": "Amputee"
}
]
},
{
"id": 9,
"mrn": "K95CKT2D1790076261",
"name": "Miss Carlee Durgan MD",
"email": "1790076261fritsch.dena@example.net",
"language": "en",
"phone": "(425) 928-9181",
"phone_country": "LT",
"phone_verified_at": null,
"address1": "13640 Feil Valleys",
"address2": "Ashleymouth, PA 77386",
"postal_code": "18768",
"city": "Jacobson Inc",
"country": "NL",
"clinic_name": "East Raegan",
"clinic_location": "48378 Karine Grove Apt. 052\nAldenstad, NY 09203",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:21.000000Z",
"updated_at": "2026-09-22T11:24:21.000000Z",
"invitation_status": null,
"acadle_invitation_status": "accepted",
"clinicians": [
{
"id": 10,
"mrn": "TEKFZQGR1790076261",
"name": "Cooper Schuppe",
"email": "1790076261hazel79@example.net",
"language": "en",
"phone": "+1 (531) 797-2396",
"phone_country": "OM",
"phone_verified_at": null,
"address1": "5267 Raphael Courts Apt. 402",
"address2": "Port Destinyfurt, NJ 18894-3154",
"postal_code": "37376-4323",
"city": "Lang, Hettinger and Marks",
"country": "GR",
"clinic_name": "Zulaport",
"clinic_location": "95357 Elwyn Crossing\nSouth Callieborough, CO 06684",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:22.000000Z",
"updated_at": "2026-09-22T11:24:22.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"pivot": {
"user_id": 9,
"assigned_user_id": 10
},
"roles": []
}
],
"devices": [
{
"id": 2,
"serial": "cac0c95d-9e4c-3d9f-94e2-b1107a6ed0e1",
"bluetooth_id": "23127a9d-a214-3772-b445-2e498b0663f8",
"company_id": null,
"model_id": null,
"amputee_id": 9,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:22.000000Z",
"updated_at": "2026-09-22T11:24:22.000000Z",
"first_config_change_at": null
}
],
"roles": [
{
"id": 7,
"name": "AcadleUser"
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view user list",
"code": "USERS:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Get current user data
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/me" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/me"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 11,
"mrn": "2VK9N4EE1790076262",
"name": "Zita Gorczany I",
"email": "1790076262hackett.melvina@example.com",
"language": "en",
"phone": "+1-304-582-5865",
"phone_country": "BD",
"phone_verified_at": null,
"address1": "181 Jerde Extensions",
"address2": "Purdybury, AR 42657",
"postal_code": "55686",
"city": "Bartoletti-Balistreri",
"country": "DE",
"clinic_name": "Lambertburgh",
"clinic_location": "5114 Krajcik Roads\nCorafurt, DC 80394",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:22.000000Z",
"updated_at": "2026-09-22T11:24:22.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 4,
"name": "Clinician"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Get other user data
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 12,
"mrn": "KX83MZPS1790076262",
"name": "Leon Koelpin",
"email": "1790076262tara.bechtelar@example.org",
"language": "en",
"phone": "1-405-636-9545",
"phone_country": "IN",
"phone_verified_at": null,
"address1": "74352 Wiegand Track Apt. 325",
"address2": "North Antwon, MS 49765-3213",
"postal_code": "36464-7132",
"city": "Donnelly Ltd",
"country": "LT",
"clinic_name": "Port Leonora",
"clinic_location": "255 Angelo Drive\nMetzland, UT 44930-8355",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:23.000000Z",
"updated_at": "2026-09-22T11:24:23.000000Z",
"invitation_status": null,
"acadle_invitation_status": null,
"roles": [
{
"id": 6,
"name": "Amputee"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view user data",
"code": "USERS:GET:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:GET:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Create new user account
requires authentication
Predefined permissions:
user.view- access to view users' data (GET /user/{id} endpoint)user.update- access to update users' data (PUT /user/{id} and POST /user/{id}/phone endpoints)user.passwordChange- access to change users' passwords (POST /user/{id}/password endpoint)user.devices- access to list of users' devices (GET /user/{id}/devices endpoint)user.tickets.view- access to listing and viewing ticketsuser.tickets.update- access to updating tickets (marking messages as read)user.tickets.send- access to sending messages in ticketsuser.tickets.close- access to closing ticketsuser.goals- access to view or manage users' goals
Example request:
curl --request POST \
"http://localhost:8000/api/user" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "mrn=MRN12345678"\
--form "name=Tom Smith"\
--form "email=test@example.com"\
--form "language=en"\
--form "address1=95597 Verda Freeway"\
--form "address2=Lakinport, IN 19037"\
--form "postal_code=72132-9545"\
--form "city=East Thaddeus"\
--form "country=HR"\
--form "clinic_name=Aether"\
--form "clinic_location=95597 Verda Freeway"\
--form "mfa_enabled=1"\
--form "mfa_method=email"\
--form "is_internal="\
--form "is_ambassador="\
--form "clinicians[]=2"\
--form "notifications_timezone=Europe/Warsaw"\
--form "notifications_at=8:00"\
--form "role=Amputee"\
--form "image=@/tmp/phpAgnBeB" \
--form "public_image=@/tmp/phpfwaHOQ" const url = new URL(
"http://localhost:8000/api/user"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('mrn', 'MRN12345678');
body.append('name', 'Tom Smith');
body.append('email', 'test@example.com');
body.append('language', 'en');
body.append('address1', '95597 Verda Freeway');
body.append('address2', 'Lakinport, IN 19037');
body.append('postal_code', '72132-9545');
body.append('city', 'East Thaddeus');
body.append('country', 'HR');
body.append('clinic_name', 'Aether');
body.append('clinic_location', '95597 Verda Freeway');
body.append('mfa_enabled', '1');
body.append('mfa_method', 'email');
body.append('is_internal', '');
body.append('is_ambassador', '');
body.append('clinicians[]', '2');
body.append('notifications_timezone', 'Europe/Warsaw');
body.append('notifications_at', '8:00');
body.append('role', 'Amputee');
body.append('image', document.querySelector('input[name="image"]').files[0]);
body.append('public_image', document.querySelector('input[name="public_image"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 13,
"mrn": "HNHBSKKL1790076263",
"name": "Ocie Hodkiewicz II",
"email": "1790076263schmitt.emely@example.net",
"language": "en",
"phone": "(434) 290-8911",
"phone_country": "AR",
"phone_verified_at": null,
"address1": "655 Bradtke Harbor",
"address2": "Lake Lindseyfort, WI 98896-7085",
"postal_code": "15880",
"city": "Kunde, Walsh and Hettinger",
"country": "LU",
"clinic_name": "Rickyfort",
"clinic_location": "87755 Ofelia Views Apt. 328\nEast Lylaville, CT 90807",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:23.000000Z",
"updated_at": "2026-09-22T11:24:23.000000Z",
"invitation_status": "accepted",
"acadle_invitation_status": null,
"roles": [
{
"id": 4,
"name": "Clinician"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create user with given role",
"code": "USERS:CREATE:INSUFFICIENT_PERMISSION"
}
Example response (403, E-mail in use (in another region)):
{
"message": "E-mail address already in use (in another region)",
"code": "USERS:CREATE:EMAIL_IN_USE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Update user account
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "mrn=MRN12345678"\
--form "name=Tom Smith"\
--form "email=test@example.com"\
--form "language=en"\
--form "address1=414 Elaina Land Apt. 478"\
--form "address2=Deangelofort, NJ 61474-2438"\
--form "postal_code=63730-3799"\
--form "city=East Robyn"\
--form "country=HR"\
--form "clinic_name=Aether"\
--form "clinic_location=414 Elaina Land Apt. 478"\
--form "image_delete=1"\
--form "mfa_enabled=1"\
--form "mfa_method=email"\
--form "active=1"\
--form "is_internal="\
--form "is_ambassador="\
--form "clinicians[]=2"\
--form "notifications_timezone=Europe/Warsaw"\
--form "notifications_at=8:00"\
--form "role=Amputee"\
--form "image=@/tmp/phpQB6mEA" \
--form "public_image=@/tmp/phpqtcwCZ" const url = new URL(
"http://localhost:8000/api/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('mrn', 'MRN12345678');
body.append('name', 'Tom Smith');
body.append('email', 'test@example.com');
body.append('language', 'en');
body.append('address1', '414 Elaina Land Apt. 478');
body.append('address2', 'Deangelofort, NJ 61474-2438');
body.append('postal_code', '63730-3799');
body.append('city', 'East Robyn');
body.append('country', 'HR');
body.append('clinic_name', 'Aether');
body.append('clinic_location', '414 Elaina Land Apt. 478');
body.append('image_delete', '1');
body.append('mfa_enabled', '1');
body.append('mfa_method', 'email');
body.append('active', '1');
body.append('is_internal', '');
body.append('is_ambassador', '');
body.append('clinicians[]', '2');
body.append('notifications_timezone', 'Europe/Warsaw');
body.append('notifications_at', '8:00');
body.append('role', 'Amputee');
body.append('image', document.querySelector('input[name="image"]').files[0]);
body.append('public_image', document.querySelector('input[name="public_image"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Example response (202):
{
"id": 14,
"mrn": "JMW8TKWD1790076263",
"name": "Myrl Bahringer III",
"email": "1790076263jerrod.lemke@example.org",
"language": "en",
"phone": "+1 (606) 508-1269",
"phone_country": "CX",
"phone_verified_at": null,
"address1": "4482 Don Summit Suite 291",
"address2": "Freidatown, DE 11887-2445",
"postal_code": "34954",
"city": "Weber, Lynch and Fahey",
"country": "LV",
"clinic_name": "East Darianamouth",
"clinic_location": "53166 Aufderhar Island\nAnastasiafort, MN 43870-7003",
"image": null,
"public_image": null,
"mfa_enabled": 0,
"mfa_method": null,
"mfa_verified_to": null,
"location_id": null,
"created_by": null,
"active": 1,
"is_internal": 0,
"is_ambassador": 0,
"notifications_timezone": null,
"notifications_at": null,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z",
"invitation_status": null,
"acadle_invitation_status": "accepted",
"roles": [
{
"id": 7,
"name": "AcadleUser"
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update user data",
"code": "USERS:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (403, Insufficient permission to assign role):
{
"message": "Insufficient permission to assign this role as ClinicAdmin",
"code": "USERS:UPDATE:INSUFFICIENT_PERMISSION_ASSIGN_ROLE"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:UPDATE:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
User ID.
mrn
string
Medical Record Number.
name
string
User full name.
email
string
User email address.
language
string
User preferred language.
phone
string
User phone number.
phone_country
string
Phone country code.
phone_verified_at
string
Phone verification date.
address1
string
Address line 1.
address2
string
Address line 2.
postal_code
string
Postal code.
city
string
City.
country
string
Country code (ISO 3166 Alpha-2).
clinic_name
string
Clinic name.
clinic_location
string
Clinic location.
image
string
User profile image URL.
mfa_enabled
boolean
Whether MFA is enabled.
mfa_method
string
Preferred MFA method.
mfa_verified_to
string
MFA session verified until.
location_id
integer
Location ID.
created_by
integer
ID of the user who created this account.
active
boolean
Whether the user account is active.
is_internal
boolean
Whether the user is an internal user.
notifications_timezone
string
Timezone for notifications.
notifications_at
string
Preferred notification time.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
invitation_status
string
User invitation status.
acadle_invitation_status
string
Acadle invitation status.
roles
object[]
User roles.
id
integer
Role ID.
name
string
Role name.
permissions
object[]
User permissions.
clinicians
object[]
Assigned clinicians.
devices
object[]
Assigned devices.
patients
object[]
Assigned patients.
invitations
object[]
User invitations.
Update user phone number
requires authentication
Phone number has to be verified after update.
Call /api/mfa/phone/verify with user-filled code after performing this operation.
If value is "0" phone number will be removed without any verification.
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/phone" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"phone\": \"+1 (208) 892-0242\",
\"phone_country\": \"US\"
}"
const url = new URL(
"http://localhost:8000/api/user/1/phone"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"phone": "+1 (208) 892-0242",
"phone_country": "US"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, Phone number removed):
{
"message": "Phone number removed",
"code": "USERS:SET_PHONE:REMOVED"
}
Example response (200, Phone number updated):
{
"message": "Verification code sent. Call /api/mfa/phone/verify to verify phone number.",
"code": "USERS:SET_PHONE:UPDATED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update user data",
"code": "USERS:SET_PHONE:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:SET_PHONE:USER_NOT_FOUND"
}
Example response (500, Code send failed):
{
"message": "Verification code sending failed",
"code": "USERS:SET_PHONE:SEND_FAILED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete user account
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/user/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "User deleted",
"code": "USERS:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete user",
"code": "USERS:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, User has existing patients or chat rooms):
{
"message": "Cannot delete: user has existing patients or chat rooms (patients: 1, chat rooms: 0)",
"code": "USERS:DELETE:HAS_PATIENTS"
}
Example response (403, User has existing devices):
{
"message": "Cannot delete: user has existing devices (as patient: 1, as clinician: 0)",
"code": "USERS:DELETE:HAS_DEVICES"
}
Example response (403, User has open P2P sessions):
{
"message": "Cannot delete: user has open P2P sessions (as patient: 0, as clinician: 1)",
"code": "USERS:DELETE:HAS_P2P_SESSIONS"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:DELETE:USER_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error: user not deleted",
"code": "USERS:DELETE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete own user account
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/user" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"password\": \"password\"
}"
const url = new URL(
"http://localhost:8000/api/user"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"password": "password"
};
fetch(url, {
method: "DELETE",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"message": "User deleted",
"code": "USERS:SELF_DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete user",
"code": "USERS:SELF_DELETE:INSUFFICIENT_PERMISSION"
}
Example response (422, Invalid password):
{
"message": "Invalid password",
"code": "USERS:SELF_DELETE:INVALID_PASSWORD"
}
Example response (500, Server error):
{
"message": "Server error: user not deleted",
"code": "USERS:SELF_DELETE:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Change other user password
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/password" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"password\": \"ut\"
}"
const url = new URL(
"http://localhost:8000/api/user/1/password"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"password": "ut"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"message": "User password changed",
"code": "USERS:PASSWORD_CHANGE:CHANGED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to change user password",
"code": "USERS:PASSWORD_CHANGE:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:PASSWORD_CHANGE:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get user devices list
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1/devices" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/devices"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 3,
"serial": "c0108c9c-ed6a-3bbb-98fc-e8f4aaafdfd7",
"bluetooth_id": "1400783a-efec-3d38-a73a-9ed30658ec8a",
"company_id": null,
"model_id": 1,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z",
"first_config_change_at": null,
"model": {
"id": 1,
"name": "Zeus hand v1",
"type": "arm",
"orientation": "right",
"active": 1,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z"
}
},
{
"id": 4,
"serial": "a46aa8a0-e9e9-3be2-86dc-34f2e8bc0eca",
"bluetooth_id": "6e4676b2-57dc-3587-a37a-e44c169fb017",
"company_id": null,
"model_id": 2,
"amputee_id": null,
"clinician_id": null,
"firmware_version_id": null,
"pcb_version_id": null,
"reverse_magnets": 0,
"is_electrode": 0,
"active": 1,
"last_activity_at": "0000-00-00 00:00:00",
"first_connected_at": null,
"measurements": null,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z",
"first_config_change_at": null,
"model": {
"id": 2,
"name": "Zeus hand v1",
"type": "arm",
"orientation": "right",
"active": 1,
"created_at": "2026-09-22T11:24:24.000000Z",
"updated_at": "2026-09-22T11:24:24.000000Z"
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to view user devices",
"code": "USERS:DEVICES:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:DEVICES:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Device ID.
serial
string
Device serial number.
bluetooth_id
string
Bluetooth identifier.
model_id
integer
Device model ID.
amputee_id
integer
Assigned patient (amputee) user ID.
firmware_version_id
integer
Firmware version ID.
pcb_version_id
integer
PCB version ID.
company_id
integer
Company ID.
reverse_magnets
boolean
Whether magnets are reversed.
is_electrode
boolean
Whether this device is an electrode.
active
boolean
Whether the device is active.
last_activity_at
string
Last activity timestamp.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
model
object
Device model details.
id
integer
Device model ID.
name
string
Model name.
type
string
Model type.
orientation
string
Model orientation.
active
boolean
Whether the model is active.
amputee
object
Assigned patient (amputee) user.
id
integer
User ID.
name
string
User full name.
email
string
User email address.
clinicians
object[]
Clinicians assigned to this device.
firmwareVersion
object
Firmware version details.
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
pcbVersion
object
PCB version details.
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
joinedDevices
object[]
Joined hand devices.
joinedElectrodes
object[]
Joined electrode devices.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Attach patient to clinician
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/user/attach" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"name@domain.com\"
}"
const url = new URL(
"http://localhost:8000/api/user/attach"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "name@domain.com"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"message": "Patient attached",
"code": "USERS:ATTACH:ATTACHED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to attach patients",
"code": "USERS:ATTACH:INSUFFICIENT_PERMISSION"
}
Example response (403, Patient is already assigned to another clinician):
{
"message": "Patient is already assigned to another clinician",
"code": "USERS:ATTACH:ALREADY_ASSIGNED"
}
Example response (403, User reached the temporary limit of attached devices):
{
"message": "Reached the limit of assigned devices",
"code": "USERS:ATTACH:LIMIT_REACHED"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:ATTACH:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Detach patient from clinician
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/user/1/detach" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/detach"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Patient detached",
"code": "USERS:DETACH:DETACHED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to detach patient",
"code": "USERS:DETACH:INSUFFICIENT_PERMISSION"
}
Example response (403, Cannot detach last clinician):
{
"message": "Cannot detach patient's last clinician",
"code": "USERS:DETACH:CANNOT_DETACH_LAST_CLINICIAN"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:DETACH:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Admin access to MFA codes
requires authentication
Requires admin.mfa_access permission.
Example request:
curl --request GET \
--get "http://localhost:8000/api/user/1/mfa-codes" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/user/1/mfa-codes"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, OK):
[
{
"id": 1,
"user_id": 1,
"code": "123456",
"channel": "email",
"expires": "2025-05-09 12:00:00"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access MFA codes",
"code": "USERS:ADMIN_MFA_ACCESS:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:ADMIN_MFA_ACCESS:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Export clinician devices
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/clinician-devices/csv" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/clinician-devices/csv"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200, CSV file):
{
"file": "https://staging-us-east-2-aether-biomedical-s3-us-bucket.s3.us-east-2.amazonaws.com/clinicians/clinicians-devices-1759228216.csv",
"expires": "2026-07-02 10:40:00"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to export clinician devices",
"code": "USERS:EXPORT_CLINICIAN_DEVICES:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get user mobile consents
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/consents" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/consents"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"user_id": 34,
"name": "esse",
"value": "et",
"created_at": "1983-01-15T05:07:34.000000Z",
"updated_at": "1981-11-27T20:02:00.000000Z"
},
{
"id": 2,
"user_id": 35,
"name": "est",
"value": "et",
"created_at": "1999-08-03T08:34:22.000000Z",
"updated_at": "2003-06-16T06:45:14.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use mobile consents",
"code": "USERS:GET_MOBILE_CONSENTS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Consent record ID.
user_id
integer
Associated user ID.
name
string
Consent name/key.
value
string
Consent value.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Set user mobile consent
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/consents" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Push notifications\",
\"value\": 1
}"
const url = new URL(
"http://localhost:8000/api/consents"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Push notifications",
"value": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
[
{
"id": 3,
"user_id": 36,
"name": "libero",
"value": "dolores",
"created_at": "1972-06-25T13:36:01.000000Z",
"updated_at": "1980-11-10T23:20:17.000000Z"
},
{
"id": 4,
"user_id": 37,
"name": "reiciendis",
"value": "placeat",
"created_at": "1996-08-01T22:14:11.000000Z",
"updated_at": "2014-04-27T20:49:10.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to use mobile consents",
"code": "USERS:SET_MOBILE_CONSENTS:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Consent record ID.
user_id
integer
Associated user ID.
name
string
Consent name/key.
value
string
Consent value.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Clear user notifications
requires authentication
Clearing notifications allow to receive another notification on same day. This endpoint deletes notifications of type:
- daily activity reminders
- goals daily summary
This endpoint is intended for testing use only.
Example request:
curl --request DELETE \
"http://localhost:8000/api/notifications/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/notifications/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"messages": "1 notifications deleted",
"code": "USERS:CLEAR_NOTIFICATIONS:CLEARED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update user data",
"code": "USERS:CLEAR_NOTIFICATIONS:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "USERS:CLEAR_NOTIFICATIONS:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Versions
API endpoints for versions management
Get software versions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/versions/software" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/software"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"name": "4.26.83",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
},
{
"id": 2,
"name": "1.47.62",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list versions",
"code": "SOFTWARE_VERSION:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Software version ID.
name
string
Version name.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create software version
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/versions/software" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"1.0\"
}"
const url = new URL(
"http://localhost:8000/api/versions/software"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "1.0"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 3,
"name": "3.95.51",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create versions",
"code": "SOFTWARE_VERSION:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Software version ID.
name
string
Version name.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete software version
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/versions/software/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/software/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Version deleted",
"code": "SOFTWARE_VERSION:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete versions",
"code": "SOFTWARE_VERSION:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, Version in use (compatibility)):
{
"message": "Cannot delete: version is used in compatibility entries (1)",
"code": "SOFTWARE_VERSION:DELETE:VERSION_IN_USE_COMPATIBILITY"
}
Example response (404, Version not found):
{
"message": "Version not found",
"code": "SOFTWARE_VERSION:DELETE:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get firmware versions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/versions/firmware" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/firmware"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 2,
"name": "1.91.50",
"file_firmware": "/tmp/fakerdK3J9R",
"file_firmware_v2": "/tmp/fakerjUo7tx",
"file_firmware_v3": "/tmp/fakerVBJVsF",
"file_firmware_v4": "/tmp/fakercdN6G8",
"file_firmware_v5": "/tmp/fakerdGQkH4",
"file_firmware_new_pcb": "/tmp/fakerGlIQfg",
"file_bootloader": "/tmp/faker064T88",
"file_bootloader_v2": "/tmp/fakerYWZR0T",
"file_bootloader_v3": "/tmp/fakerTbxnuf",
"file_bootloader_v4": "/tmp/fakerdIBJ8z",
"changelog": "Quos velit quia voluptatem dolorum vel et. Illum maxime minus vel id. Cumque sunt dolore id iure quas. Doloremque eius error distinctio et illo ipsam beatae.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
},
{
"id": 3,
"name": "1.51.73",
"file_firmware": "/tmp/fakerm7Wp2P",
"file_firmware_v2": "/tmp/fakerpE8NwP",
"file_firmware_v3": "/tmp/fakerDBVzlP",
"file_firmware_v4": "/tmp/fakerPb9QNv",
"file_firmware_v5": "/tmp/fakerkpwoXC",
"file_firmware_new_pcb": "/tmp/fakerbTuoec",
"file_bootloader": "/tmp/fakerSHZ8Zc",
"file_bootloader_v2": "/tmp/faker9d0GWk",
"file_bootloader_v3": "/tmp/faker3lCZc6",
"file_bootloader_v4": "/tmp/fakerh4sCpE",
"changelog": "Dolor quae repellat voluptas quidem. Et temporibus aut explicabo dolorum ut. Voluptatem porro sunt sunt aut.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list versions",
"code": "FIRMWARE_VERSION:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create firmware version
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/versions/firmware" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "name=1.0"\
--form "models[]=1"\
--form "changelog[][language]=en"\
--form "changelog[][changelog]=Fixed bug with the connection"\
--form "file_firmware=@/tmp/phpD7LxDI" \
--form "file_firmware_v2=@/tmp/php4t3eqA" \
--form "file_firmware_v3=@/tmp/phpYoDANS" \
--form "file_firmware_v4=@/tmp/phpgV81Cg" \
--form "file_firmware_v5=@/tmp/phpQ5t9iY" \
--form "file_firmware_new_pcb=@/tmp/phpwiVEOx" \
--form "file_bootloader=@/tmp/phppjJfka" \
--form "file_bootloader_v2=@/tmp/phprHcMjf" \
--form "file_bootloader_v3=@/tmp/phpyihE8b" \
--form "file_bootloader_v4=@/tmp/php2J7rJj" const url = new URL(
"http://localhost:8000/api/versions/firmware"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('name', '1.0');
body.append('models[]', '1');
body.append('changelog[][language]', 'en');
body.append('changelog[][changelog]', 'Fixed bug with the connection');
body.append('file_firmware', document.querySelector('input[name="file_firmware"]').files[0]);
body.append('file_firmware_v2', document.querySelector('input[name="file_firmware_v2"]').files[0]);
body.append('file_firmware_v3', document.querySelector('input[name="file_firmware_v3"]').files[0]);
body.append('file_firmware_v4', document.querySelector('input[name="file_firmware_v4"]').files[0]);
body.append('file_firmware_v5', document.querySelector('input[name="file_firmware_v5"]').files[0]);
body.append('file_firmware_new_pcb', document.querySelector('input[name="file_firmware_new_pcb"]').files[0]);
body.append('file_bootloader', document.querySelector('input[name="file_bootloader"]').files[0]);
body.append('file_bootloader_v2', document.querySelector('input[name="file_bootloader_v2"]').files[0]);
body.append('file_bootloader_v3', document.querySelector('input[name="file_bootloader_v3"]').files[0]);
body.append('file_bootloader_v4', document.querySelector('input[name="file_bootloader_v4"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 4,
"name": "0.98.86",
"file_firmware": "/tmp/fakerKqxXOo",
"file_firmware_v2": "/tmp/fakerxnkHyp",
"file_firmware_v3": "/tmp/fakerR5llD8",
"file_firmware_v4": "/tmp/fakerWZIN7p",
"file_firmware_v5": "/tmp/fakerJG9gep",
"file_firmware_new_pcb": "/tmp/fakereck2Av",
"file_bootloader": "/tmp/faker5w63bq",
"file_bootloader_v2": "/tmp/faker4Cuv6y",
"file_bootloader_v3": "/tmp/fakerG9KSZF",
"file_bootloader_v4": "/tmp/fakersWKZ1r",
"changelog": "Consequatur optio delectus maxime quasi. Expedita repellendus natus ullam voluptatibus consequatur eum itaque. Ea omnis fugit eum ex molestias.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create versions",
"code": "FIRMWARE_VERSION:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update firmware version
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/versions/firmware/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "name=1.0"\
--form "models[]=1"\
--form "file_firmware_delete=1"\
--form "file_firmware_v2_delete=1"\
--form "file_firmware_v3_delete=1"\
--form "file_firmware_v4_delete=1"\
--form "file_firmware_v5_delete=1"\
--form "file_firmware_new_pcb_delete=1"\
--form "file_bootloader_delete=1"\
--form "file_bootloader_v2_delete=1"\
--form "file_bootloader_v3_delete=1"\
--form "file_bootloader_v4_delete=1"\
--form "changelog[][language]=en"\
--form "changelog[][changelog]=Fixed bug with the connection"\
--form "file_firmware=@/tmp/phpfsWWI4" \
--form "file_firmware_v2=@/tmp/phpqB0ypE" \
--form "file_firmware_v3=@/tmp/phpJgxaza" \
--form "file_firmware_v4=@/tmp/phpNKWqif" \
--form "file_firmware_v5=@/tmp/phptq3EeP" \
--form "file_firmware_new_pcb=@/tmp/phpc2xftZ" \
--form "file_bootloader=@/tmp/php7ELWPE" \
--form "file_bootloader_v2=@/tmp/phpKzRgLf" \
--form "file_bootloader_v3=@/tmp/phptSAnwu" \
--form "file_bootloader_v4=@/tmp/phplBHVNK" const url = new URL(
"http://localhost:8000/api/versions/firmware/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('name', '1.0');
body.append('models[]', '1');
body.append('file_firmware_delete', '1');
body.append('file_firmware_v2_delete', '1');
body.append('file_firmware_v3_delete', '1');
body.append('file_firmware_v4_delete', '1');
body.append('file_firmware_v5_delete', '1');
body.append('file_firmware_new_pcb_delete', '1');
body.append('file_bootloader_delete', '1');
body.append('file_bootloader_v2_delete', '1');
body.append('file_bootloader_v3_delete', '1');
body.append('file_bootloader_v4_delete', '1');
body.append('changelog[][language]', 'en');
body.append('changelog[][changelog]', 'Fixed bug with the connection');
body.append('file_firmware', document.querySelector('input[name="file_firmware"]').files[0]);
body.append('file_firmware_v2', document.querySelector('input[name="file_firmware_v2"]').files[0]);
body.append('file_firmware_v3', document.querySelector('input[name="file_firmware_v3"]').files[0]);
body.append('file_firmware_v4', document.querySelector('input[name="file_firmware_v4"]').files[0]);
body.append('file_firmware_v5', document.querySelector('input[name="file_firmware_v5"]').files[0]);
body.append('file_firmware_new_pcb', document.querySelector('input[name="file_firmware_new_pcb"]').files[0]);
body.append('file_bootloader', document.querySelector('input[name="file_bootloader"]').files[0]);
body.append('file_bootloader_v2', document.querySelector('input[name="file_bootloader_v2"]').files[0]);
body.append('file_bootloader_v3', document.querySelector('input[name="file_bootloader_v3"]').files[0]);
body.append('file_bootloader_v4', document.querySelector('input[name="file_bootloader_v4"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Example response (201):
{
"id": 5,
"name": "5.81.72",
"file_firmware": "/tmp/fakerbxC0Zu",
"file_firmware_v2": "/tmp/fakerkUIe1w",
"file_firmware_v3": "/tmp/fakerHZuRkJ",
"file_firmware_v4": "/tmp/fakerNglNJ1",
"file_firmware_v5": "/tmp/fakerzLO6U4",
"file_firmware_new_pcb": "/tmp/faker6XdwmL",
"file_bootloader": "/tmp/fakerTxy7Vc",
"file_bootloader_v2": "/tmp/fakerYFmT2P",
"file_bootloader_v3": "/tmp/fakerCSQH9x",
"file_bootloader_v4": "/tmp/fakerVcOpBh",
"changelog": "Rerum atque et eligendi omnis. Itaque veniam dignissimos labore. Repudiandae architecto dolor corporis veritatis accusantium recusandae voluptatem. Sapiente sed ad provident non est.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update versions",
"code": "FIRMWARE_VERSION:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Version not found):
{
"message": "Version not found",
"code": "FIRMWARE_VERSION:UPDATE:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Firmware version ID.
name
string
Version name.
file_firmware
string
Firmware file URL.
file_firmware_v2
string
Firmware v2 file URL.
file_firmware_v3
string
Firmware v3 file URL.
file_firmware_v4
string
Firmware v4 file URL.
file_firmware_v5
string
Firmware v5 file URL.
file_firmware_new_pcb
string
New PCB firmware file URL.
file_bootloader
string
Bootloader file URL.
file_bootloader_v2
string
Bootloader v2 file URL.
file_bootloader_v3
string
Bootloader v3 file URL.
file_bootloader_v4
string
Bootloader v4 file URL.
changelog
string
Changelog file URL.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete firmware version
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/versions/firmware/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/firmware/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Version deleted",
"code": "FIRMWARE_VERSION:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete versions",
"code": "FIRMWARE_VERSION:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, Version in use (compatibility)):
{
"message": "Cannot delete: version is used in compatibility entries (1)",
"code": "FIRMWARE_VERSION:DELETE:VERSION_IN_USE_COMPATIBILITY"
}
Example response (403, Version in use (device)):
{
"message": "Cannot delete: version is assigned to devices (1)",
"code": "FIRMWARE_VERSION:DELETE:VERSION_IN_USE_DEVICE"
}
Example response (404, Version not found):
{
"message": "Version not found",
"code": "FIRMWARE_VERSION:DELETE:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get PCB versions
requires authentication
Example request:
curl --request GET \
--get "http://localhost:8000/api/versions/pcb" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/pcb"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 2,
"name": "8.19.20",
"hardware_id": "",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
},
{
"id": 3,
"name": "6.15.63",
"hardware_id": "",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list versions",
"code": "PCB_VERSION:LIST:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Create PCB version
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/versions/pcb" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"1.0\",
\"models\": [
1
],
\"hardware_id\": \"1\"
}"
const url = new URL(
"http://localhost:8000/api/versions/pcb"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "1.0",
"models": [
1
],
"hardware_id": "1"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 4,
"name": "9.18.5",
"hardware_id": "",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to create versions",
"code": "PCB_VERSION:CREATE:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Update PCB version
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/versions/pcb/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"1.0\",
\"models\": [
1
],
\"hardware_id\": \"1\"
}"
const url = new URL(
"http://localhost:8000/api/versions/pcb/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "1.0",
"models": [
1
],
"hardware_id": "1"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 5,
"name": "3.68.21",
"hardware_id": "",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update versions",
"code": "PCB_VERSION:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Version not found):
{
"message": "Version not found",
"code": "PCB_VERSION:UPDATE:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
PCB version ID.
name
string
Version name.
hardware_id
string
Hardware identifier.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
Delete PCB version
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/versions/pcb/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/pcb/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Version deleted",
"code": "PCB_VERSION:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete versions",
"code": "PCB_VERSION:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (403, Version in use (compatibility)):
{
"message": "Cannot delete: version is used in compatibility entries (1)",
"code": "PCB_VERSION:DELETE:VERSION_IN_USE_COMPATIBILITY"
}
Example response (403, Version in use (device)):
{
"message": "Cannot delete: version is assigned to devices (1)",
"code": "PCB_VERSION:DELETE:VERSION_IN_USE_DEVICE"
}
Example response (404, Version not found):
{
"message": "Version not found",
"code": "PCB_VERSION:DELETE:VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List compatibilities
requires authentication
Most typical scenarios to use compatibility matrix:
- full matrix (no filters) - for admin panel displaying,
- filtered by all of the versions (software, firmware, PCB and device model) - for checking specific scenario compatibility and supported features.
Example request:
curl --request GET \
--get "http://localhost:8000/api/versions/compatibility?model=1&software=1.2&firmware=1.5&pcb=1.0&summary=" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/compatibility"
);
const params = {
"model": "1",
"software": "1.2",
"firmware": "1.5",
"pcb": "1.0",
"summary": "0",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"paginator": {
"total": 2,
"count": 2,
"perpage": 20,
"current_page": 1,
"last_page": 1
},
"items": [
{
"id": 1,
"device_model_id": 10,
"software_version_id": 4,
"firmware_version_id": 14,
"pcb_version_id": 6,
"is_fully_compatible": 0,
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"features": [
{
"id": 1,
"compatibility_id": 1,
"feature_id": 5,
"is_compatible": 0,
"reason": "Nihil est omnis distinctio ratione minus. Eum officia quae non ut sapiente fugit explicabo voluptatibus. Veniam molestiae corrupti consequatur voluptatem sapiente quis nobis.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 5,
"name": "black",
"slug": "aspernatur-qui-consequatur-minus-ut-veritatis-soluta-in",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
},
{
"id": 2,
"compatibility_id": 1,
"feature_id": 7,
"is_compatible": 1,
"reason": "Sit quis nisi porro laboriosam. Quis enim veniam voluptas. Esse illum quam inventore vel. Facilis molestiae quam veniam doloribus. Fugit assumenda quos aut beatae. Quo alias libero et non numquam ut.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 7,
"name": "white",
"slug": "et-ipsam-eos-omnis-qui-dolorum-alias",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
},
{
"id": 3,
"compatibility_id": 1,
"feature_id": 9,
"is_compatible": 1,
"reason": "Quis debitis distinctio iusto odio. Commodi itaque in aliquid voluptatem adipisci. Vero delectus iste culpa quia vero.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 9,
"name": "lime",
"slug": "voluptatem-officiis-qui-nulla-sit-itaque-quasi",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
}
]
},
{
"id": 5,
"device_model_id": 14,
"software_version_id": 8,
"firmware_version_id": 18,
"pcb_version_id": 10,
"is_fully_compatible": 1,
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"features": [
{
"id": 4,
"compatibility_id": 5,
"feature_id": 10,
"is_compatible": 1,
"reason": "Omnis consequatur consequatur aperiam ullam non est molestias magni. Qui quaerat corporis consequatur accusamus. Suscipit itaque est qui doloribus quidem dolore.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 10,
"name": "lime",
"slug": "ex-qui-repudiandae-aperiam-aut",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
},
{
"id": 5,
"compatibility_id": 5,
"feature_id": 12,
"is_compatible": 1,
"reason": "At mollitia aspernatur deserunt fuga sit ut quae. Nam impedit sequi cum culpa. Qui dolore voluptatibus non. Nemo in cumque iure sed omnis similique.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 12,
"name": "blue",
"slug": "qui-quidem-accusantium-laudantium-doloribus-dolorem-veritatis-voluptatem",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
},
{
"id": 6,
"compatibility_id": 5,
"feature_id": 14,
"is_compatible": 1,
"reason": "Voluptas sit illo dolores odio est dolor ad. Ab maxime officiis qui hic. Blanditiis exercitationem eaque aut quae consequatur laboriosam omnis.",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z",
"feature": {
"id": 14,
"name": "purple",
"slug": "accusamus-iusto-nemo-et-et-dicta-ut",
"created_at": "2026-09-22T11:26:29.000000Z",
"updated_at": "2026-09-22T11:26:29.000000Z"
}
}
]
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to list versions compatibilities",
"code": "COMPATIBILITY:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, Device model not found):
{
"message": "Device model not found",
"code": "COMPATIBILITY:LIST:DEVICE_MODEL_NOT_FOUND"
}
Example response (404, Software version not found):
{
"message": "Software version not found",
"code": "COMPATIBILITY:LIST:SOFTWARE_VERSION_NOT_FOUND"
}
Example response (404, Firmware version not found):
{
"message": "Firmware version not found",
"code": "COMPATIBILITY:LIST:FIRMWARE_VERSION_NOT_FOUND"
}
Example response (404, PCB version not found):
{
"message": "PCB version not found",
"code": "COMPATIBILITY:LIST:PCB_VERSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
items
object
id
integer
Compatibility entry ID.
device_model_id
integer
Associated device model ID.
software_version_id
integer
Associated software version ID.
firmware_version_id
integer
Associated firmware version ID.
pcb_version_id
integer
Associated PCB version ID.
is_fully_compatible
boolean
Whether all versions are fully compatible.
note
string
Compatibility note.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
features
object[]
Associated compatibility features.
paginator
object
total
integer
Total number of items.
count
integer
Number of items on current page.
perpage
integer
Items per page.
current_page
integer
Current page number.
last_page
integer
Last page number.
Add compatibility
requires authentication
Adds or updates compatibility matrix with assigned features. You can specify many versions for each list.
Example request:
curl --request POST \
"http://localhost:8000/api/versions/compatibility" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"device_models\": [
1
],
\"software_versions\": [
1
],
\"firmware_versions\": [
1
],
\"pcb_versions\": [
1
],
\"is_fully_compatible\": true,
\"features\": [
{
\"feature_id\": 1,
\"compatible\": true,
\"reason\": \"Firmware does not support...\"
}
]
}"
const url = new URL(
"http://localhost:8000/api/versions/compatibility"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"device_models": [
1
],
"software_versions": [
1
],
"firmware_versions": [
1
],
"pcb_versions": [
1
],
"is_fully_compatible": true,
"features": [
{
"feature_id": 1,
"compatible": true,
"reason": "Firmware does not support..."
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202, OK):
{
"added": 1,
"updated": 0,
"not_changed": 0
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to add versions compatibility",
"code": "COMPATIBILITY:ADD:INSUFFICIENT_PERMISSION"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update compatibility
requires authentication
Example request:
curl --request PUT \
"http://localhost:8000/api/versions/compatibility/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"device_model_id\": 10,
\"software_version_id\": 1,
\"firmware_version_id\": 9,
\"pcb_version_id\": 5,
\"is_fully_compatible\": true,
\"features\": [
{
\"id\": 1,
\"feature_id\": 1,
\"compatible\": true,
\"reason\": \"Firmware does not support...\",
\"delete\": true
}
]
}"
const url = new URL(
"http://localhost:8000/api/versions/compatibility/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"device_model_id": 10,
"software_version_id": 1,
"firmware_version_id": 9,
"pcb_version_id": 5,
"is_fully_compatible": true,
"features": [
{
"id": 1,
"feature_id": 1,
"compatible": true,
"reason": "Firmware does not support...",
"delete": true
}
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (202):
{
"id": 9,
"device_model_id": 18,
"software_version_id": 12,
"firmware_version_id": 22,
"pcb_version_id": 14,
"is_fully_compatible": 0,
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z",
"features": [
{
"id": 7,
"compatibility_id": 9,
"feature_id": 15,
"is_compatible": 0,
"reason": "Cumque modi quibusdam qui eaque libero saepe est et. Qui voluptas ab quis fugit. Fugiat rem ea sit porro ad. Iusto tenetur atque soluta saepe.",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z",
"feature": {
"id": 15,
"name": "purple",
"slug": "porro-alias-velit-aut-praesentium",
"created_at": "2026-09-22T11:26:30.000000Z",
"updated_at": "2026-09-22T11:26:30.000000Z"
}
}
]
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update versions compatibility",
"code": "COMPATIBILITY:UPDATE:INSUFFICIENT_PERMISSION"
}
Example response (404, Versions Compatibility not found):
{
"message": "Versions compatibility not found",
"code": "COMPATIBILITY:UPDATE:COMPATIBILITY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Compatibility entry ID.
device_model_id
integer
Associated device model ID.
software_version_id
integer
Associated software version ID.
firmware_version_id
integer
Associated firmware version ID.
pcb_version_id
integer
Associated PCB version ID.
is_fully_compatible
boolean
Whether all versions are fully compatible.
note
string
Compatibility note.
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
features
object[]
Associated compatibility features.
Delete compatibility
requires authentication
Example request:
curl --request DELETE \
"http://localhost:8000/api/versions/compatibility/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/versions/compatibility/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Versions compatibility deleted",
"code": "COMPATIBILITY:DELETE:DELETED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to delete versions compatibility",
"code": "COMPATIBILITY:DELETE:INSUFFICIENT_PERMISSION"
}
Example response (404, Versions compatibility not found):
{
"message": "Versions compatibility not found",
"code": "COMPATIBILITY:DELETE:COMPATIBILITY_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Video sessions
API endpoints for managing video sessions
List video sessions
requires authentication
Returns list of open video sessions. For most cases there should be exactly one entry (open/active session) or exactly zero entries (empty array, no open sessions).
Example request:
curl --request GET \
--get "http://localhost:8000/api/sessions/video/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/sessions/video/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"id": 1,
"moderator_id": 127,
"guest_id": 128,
"jwt_moderator": "c632a6ac63ec64dd2bec50c1535e96d21c7ab3335eb7a5c488326a3ec6c6e430",
"jwt_guest": "16149626b0365e04a9a52d02e17ca8aeb63680b9f5ee2ba334b0b1a38a833cfe",
"room_name": "room_1dd520ca41f1a2651c88f14e7c30ec23",
"expires": 1790077222,
"status": "open",
"created_at": "2026-09-22T11:25:23.000000Z",
"updated_at": "2026-09-22T11:25:23.000000Z"
},
{
"id": 2,
"moderator_id": 131,
"guest_id": 132,
"jwt_moderator": "49321648dc8383b8ba73c037dbcdb14873222077d3709bffe454100e5f809773",
"jwt_guest": "b6cf348bc9b1a71d9db0ce76c3b2645a3d57e2a6b2119b58a236adbef5e05c43",
"room_name": "room_8ac96f748ba2169f71453acb259bbe8f",
"expires": 1790077224,
"status": "open",
"created_at": "2026-09-22T11:25:25.000000Z",
"updated_at": "2026-09-22T11:25:25.000000Z"
}
]
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to access video session",
"code": "VIDEO_SESSIONS:LIST:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "VIDEO_SESSIONS:LIST:USER_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Video session ID.
moderator_id
integer
Moderator user ID.
guest_id
integer
Guest user ID.
jwt_moderator
string
JWT token for the moderator.
jwt_guest
string
JWT token for the guest.
room_name
string
Video room name.
expires
integer
Session expiry as Unix timestamp.
status
string
Session status.
Must be one of:openexpiredclosed
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
moderator
object
Moderator user.
guest
object
Guest user.
Initialize video session
requires authentication
Creates JWT (JSON Web Token) and room name for Jitsi session. Logged-in user is a moderator of the session. JWT lifetime is 15 minutes.
Example request:
curl --request POST \
"http://localhost:8000/api/sessions/video/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/sessions/video/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (201):
{
"id": 3,
"moderator_id": 135,
"guest_id": 136,
"jwt_moderator": "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf",
"jwt_guest": "cde4b93a14c6cbe79900fa2eca15be1b37d8dd6723b851aebb307962a49f42f4",
"room_name": "room_5ba49b0a0df1a59b13b8a97b29990d5c",
"expires": 1790077226,
"status": "open",
"created_at": "2026-09-22T11:25:27.000000Z",
"updated_at": "2026-09-22T11:25:27.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to initialize video session",
"code": "VIDEO_SESSIONS:INIT:INSUFFICIENT_PERMISSION"
}
Example response (404, User not found):
{
"message": "User not found",
"code": "VIDEO_SESSIONS:INIT:USER_NOT_FOUND"
}
Example response (500, Server error):
{
"message": "Server error",
"code": "VIDEO_SESSIONS:INIT:SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Video session ID.
moderator_id
integer
Moderator user ID.
guest_id
integer
Guest user ID.
jwt_moderator
string
JWT token for the moderator.
jwt_guest
string
JWT token for the guest.
room_name
string
Video room name.
expires
integer
Session expiry as Unix timestamp.
status
string
Session status.
Must be one of:openexpiredclosed
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
moderator
object
Moderator user.
guest
object
Guest user.
Refresh video session
requires authentication
Refreshes video session JWT tokens to extend session lifetime.
Example request:
curl --request POST \
"http://localhost:8000/api/sessions/video/1/refresh" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/sessions/video/1/refresh"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (202):
{
"id": 4,
"moderator_id": 139,
"guest_id": 140,
"jwt_moderator": "4d8e7438a0573b2895ab0f49fe82596b564e8ba985bc8be657ac764bbd0d7895",
"jwt_guest": "a941ea708fa6dbcb9f4dc76bbc141a619d5a3bdbb11da8c8cfe859005277d504",
"room_name": "room_707e68c26207a48617aecfb1655039c5",
"expires": 1790077227,
"status": "open",
"created_at": "2026-09-22T11:25:28.000000Z",
"updated_at": "2026-09-22T11:25:28.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to refresh video session",
"code": "VIDEO_SESSIONS:REFRESH:INSUFFICIENT_PERMISSION"
}
Example response (404, Session not found):
{
"message": "Video session not found",
"code": "VIDEO_SESSIONS:REFRESH:SESSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
Video session ID.
moderator_id
integer
Moderator user ID.
guest_id
integer
Guest user ID.
jwt_moderator
string
JWT token for the moderator.
jwt_guest
string
JWT token for the guest.
room_name
string
Video room name.
expires
integer
Session expiry as Unix timestamp.
status
string
Session status.
Must be one of:openexpiredclosed
created_at
string
Creation timestamp.
updated_at
string
Last update timestamp.
moderator
object
Moderator user.
guest
object
Guest user.
Close video session
requires authentication
Marks video session (database entry) as closed. Does not close session on Jitsi side.
Example request:
curl --request DELETE \
"http://localhost:8000/api/sessions/video/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost:8000/api/sessions/video/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (202, OK):
{
"message": "Video session closed",
"code": "VIDEO_SESSIONS:CLOSE:CLOSED"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to close video session",
"code": "VIDEO_SESSIONS:CLOSE:INSUFFICIENT_PERMISSION"
}
Example response (404, Session not found):
{
"message": "Video session not found",
"code": "VIDEO_SESSIONS:CLOSE:SESSION_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Invite technical support
requires authentication
Sends notification to Slack channel. Link to meeting is valid for 10 minutes.
Example request:
curl --request POST \
"http://localhost:8000/api/sessions/video/invite-support/1" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"room\": \"room_1081c785cf1464e4d6ebc3976561d490\",
\"description\": \"Grip switching is not working, please join.\"
}"
const url = new URL(
"http://localhost:8000/api/sessions/video/invite-support/1"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"room": "room_1081c785cf1464e4d6ebc3976561d490",
"description": "Grip switching is not working, please join."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200, OK):
{
"response": "success",
"code": "VIDEO_SESSIONS:INVITE_TECH_SUPPORT:SUCCESS"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to invite tech support",
"code": "VIDEO_SESSIONS:INVITE_TECH_SUPPORT:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "VIDEO_SESSIONS:INVITE_TECH_SUPPORT:DEVICE_NOT_FOUND"
}
Example response (500, Request failed):
{
"response": "invalid_payload",
"code": "VIDEO_SESSIONS:INVITE_TECH_SUPPORT:FAILED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Wizard
Endpoints related to the device setup wizard prompt (Guide vs Configurator choice)
Save wizard prompt choice
requires authentication
Example request:
curl --request POST \
"http://localhost:8000/api/device/1/wizard-prompt" \
--header "Authorization: Bearer {ACCESS_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"choice\": \"guide\",
\"dont_ask_again\": false
}"
const url = new URL(
"http://localhost:8000/api/device/1/wizard-prompt"
);
const headers = {
"Authorization": "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"choice": "guide",
"dont_ask_again": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 1,
"user_id": 79,
"device_id": 68,
"choice": "dismissed",
"dont_ask_again": 0,
"created_at": "2026-09-22T11:24:58.000000Z",
"updated_at": "2026-09-22T11:24:58.000000Z"
}
Example response (403, Insufficient permission):
{
"message": "Insufficient permission to update device config",
"code": "WIZARD:SAVE_PROMPT:INSUFFICIENT_PERMISSION"
}
Example response (404, Device not found):
{
"message": "Device not found",
"code": "WIZARD:SAVE_PROMPT:DEVICE_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.