Groups and permissions
Manage your organisation's groups and the permissions they carry. There are four permissions a connection can never give.
This page is for the developer managing your organisation's groups from another system.
It covers listing, adding, changing and deleting groups, setting the permissions each group holds, and the four permissions a connection may not give.
Before you start
Each person is in one group at most. What a person can do in InMyWords is decided by the permissions of their group.
- Where to send calls. The base address is
https://app.inmywords.chat/api/integrations/v1/ - Send your key with every request.
Authorization: Bearer imw_<64 hex characters> - The scopes you need. Reading needs
groups:read. Adding, editing and deleting groups, and setting their permissions, needgroups:write. - How values are written. Ids are strings of digits, such as
"1842". Times are ISO 8601 in UTC. Field names are snake_case. - How answers are shaped. One item comes back as
{"data": {...}}. A list comes back as{"data": [...], "next_cursor": "..."}, andnext_cursoris null on the last page. - Reading a list. A list takes
limitandcursor.limitis 50 by default and 100 at most, and a larger value is reduced to 100. Groups have no change time, soupdated_sinceis not taken here and answers 400invalid_request. Alimitorcursorthat cannot be read answers 400invalid_request. - Retrying safely. A POST takes an
Idempotency-Keyheader. The same key with the same body within 24 hours gives you the first result back. The same key with a different body answers 422idempotency_key_reused.
Endpoints
| Method | Path | Scope |
|---|---|---|
| GET | /groups | groups:read |
| GET | /groups/{id} | groups:read |
| POST | /groups | groups:write |
| PATCH | /groups/{id} | groups:write |
| DELETE | /groups/{id} | groups:write |
| GET | /groups/{id}/permissions | groups:read |
| PUT | /groups/{id}/permissions | groups:write |
| POST | /groups/{id}/permissions | groups:write |
| DELETE | /groups/{id}/permissions/{code} | groups:write |
| GET | /permissions | groups:read |
What a group looks like
| Field | Type | Notes |
|---|---|---|
id | string | |
name | string | At most 120 characters. |
description | string or null | At most 500 characters. |
permissions | list of codes | |
require_two_factor | boolean | Members must sign in with a second factor. |
allow_hide_templates | boolean | Members can hide templates they do not use. |
member_count | integer | |
created_at | time |
{
"data": {
"id": "57",
"name": "Housing officers",
"description": "Front-line housing advice.",
"permissions": ["read_conversations", "manage_cases"],
"require_two_factor": true,
"allow_hide_templates": true,
"member_count": 12,
"created_at": "2026-03-11T14:55:02Z"
}
}
Permissions
| Code | Name |
|---|---|
manage_users | Manage users |
manage_billing | Manage billing |
manage_templates | Manage templates |
manage_groups | Manage groups |
manage_knowledge | Manage organisation knowledge |
read_conversations | Read conversations |
view_audit | Audit trail |
view_statistics | Statistics |
manage_cases | Cases |
view_tickets | Support tickets |
manage_integrations | Manage integrations |
GET /permissions gives you this list with the names, so your system does not need to hard-code it.
A connection cannot give a group manage_users, manage_billing, manage_integrations or manage_groups. Those are given in InMyWords, by a person in your organisation. manage_groups is among them because a member of a group holding it can give the other three on the Groups page.
curl https://app.inmywords.chat/api/integrations/v1/permissions \
-H "Authorization: Bearer imw_..."
{
"data": [
{"code": "manage_users", "name": "Manage users"},
{"code": "read_conversations", "name": "Read conversations"}
],
"next_cursor": null
}
List your groups
curl https://app.inmywords.chat/api/integrations/v1/groups \
-H "Authorization: Bearer imw_..."
Add a group
Send a name, and if you want them, a description, permissions, require_two_factor and allow_hide_templates. The answer is 201 with the new group.
curl -X POST https://app.inmywords.chat/api/integrations/v1/groups \
-H "Authorization: Bearer imw_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0b9e4f1a-2c3d-4e5f-8a9b-7c6d5e4f3a2b" \
-d '{"name": "Housing officers", "description": "Front-line housing advice.", "permissions": ["read_conversations", "manage_cases"], "require_two_factor": true}'
Change a group
Send any of name, description, permissions, require_two_factor and allow_hide_templates. Anything you leave out stays as it is. If you send permissions, it replaces the whole list.
curl -X PATCH https://app.inmywords.chat/api/integrations/v1/groups/57 \
-H "Authorization: Bearer imw_..." \
-H "Content-Type: application/json" \
-d '{"name": "Housing and tenancy officers"}'
Delete a group
A group that holds cases cannot be deleted. The answer is 409 group_holds_cases, with the number of cases in the message. Move the cases to another group in InMyWords first.
The group's members keep their accounts and are left in no group. The answer is 204 with no body.
curl -X DELETE https://app.inmywords.chat/api/integrations/v1/groups/57 \
-H "Authorization: Bearer imw_..."
Set a group's permissions
- Replace the list.
PUT /groups/{id}/permissions, with the body{"permissions": [...]}. - Add one.
POST /groups/{id}/permissions, with the body{"code": "..."}. - Remove one.
DELETE /groups/{id}/permissions/{code}.
Each gives you back the group's permissions after the change. A code that does not exist answers 422 unknown_permission.
curl -X PUT https://app.inmywords.chat/api/integrations/v1/groups/57/permissions \
-H "Authorization: Bearer imw_..." \
-H "Content-Type: application/json" \
-d '{"permissions": ["read_conversations", "manage_cases", "view_statistics"]}'
curl -X POST https://app.inmywords.chat/api/integrations/v1/groups/57/permissions \
-H "Authorization: Bearer imw_..." \
-H "Content-Type: application/json" \
-d '{"code": "view_tickets"}'
curl -X DELETE https://app.inmywords.chat/api/integrations/v1/groups/57/permissions/view_tickets \
-H "Authorization: Bearer imw_..."
{
"data": ["read_conversations", "manage_cases", "view_statistics"]
}
Rules on every change
- Four permissions cannot be given. Any change that would give a group
manage_users,manage_billing,manage_integrationsormanage_groupsanswers 403permission_not_grantable. That covers a new group holding one, aPUTorPATCHwhose list includes one, and aPOSTof one. - They can be taken away. Removing one of those four from a group is allowed.
- Somebody can always manage people. Your organisation always keeps at least one enabled person in a group that holds
manage_users. Removingmanage_usersfrom the last such group, or deleting it, answers 409last_people_manager. - Translation settings stay in InMyWords. A group's translation wording, formality and explanation level are set in InMyWords, not through the API.
- Only your own groups. A group of InMyWords, or of another organisation, answers 404
not_found. - Every change is recorded. Each one is written on your organisation's audit trail under the connection's name.
Errors
Every error comes back as {"error": {"code": "...", "message": "..."}}.
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | A limit or cursor cannot be read, or updated_since was sent. |
| 401 | unauthorised | There is no key, or the key is not valid. |
| 403 | module_off | Integrations are not switched on for your organisation. |
| 403 | scope_missing | The connection does not hold the scope. |
| 403 | permission_not_grantable | The change would give a group a permission a connection cannot give. |
| 404 | not_found | There is no such group in your organisation. |
| 409 | group_holds_cases | The group holds cases. |
| 409 | last_people_manager | The change would leave nobody able to manage people. |
| 422 | validation_failed | A field is missing or not valid. |
| 422 | unknown_permission | A permission code does not exist. |
| 422 | idempotency_key_reused | The key was used before with a different body. |
| 429 | rate_limited | Too many calls this minute. Wait for Retry-After seconds. |