Manage roles and permissions

Beta

Most endpoints of the emnify REST API require a specific permission, which is a pair of a resource and an action. A few require none, such as authentication. The three system roles (Administrator, User, and Observer) cover common access patterns, but they can’t be edited. To grant an exact set of permissions, create a custom role and assign it to users.

This guide shows how to manage roles and permissions via the API:

Before you begin

All requests require an authentication token. Managing roles and users requires a role that includes the user and role management permissions, such as Administrator.

In these requests, orgId accepts either a numeric Workspace ID or the literal my, which targets your own Workspace. Use a numeric ID when you administer a child Workspace.

List available permissions

To see every permission you can assign, request the permission catalog:

GET
/api/v1/organisation/:orgId/permission
1curl https://cdn.emnify.net/api/v1/organisation/my/permission \
2 -H "Authorization: Bearer <token>"

Each entry pairs a resource with an action and lists the API routes that the permission guards under entrypoints:

Response
1[
2 {
3 "id": 201,
4 "resource": "Endpoint",
5 "action": "List",
6 "created_at": "2026-01-10T08:00:00.000Z",
7 "updated_at": "2026-06-20T14:30:00.000Z",
8 "deprecated_at": null,
9 "entrypoints": {
10 "rest": [
11 {
12 "method": "GET",
13 "path": "/api/v1/endpoint",
14 "created_at": "2026-01-10T08:00:00.000Z",
15 "updated_at": "2026-01-10T08:00:00.000Z",
16 "deprecated_at": null
17 }
18 ],
19 "graphql": [
20 {
21 "type": "query",
22 "path": "endpoints",
23 "created_at": "2026-01-10T08:00:00.000Z",
24 "updated_at": "2026-01-10T08:00:00.000Z",
25 "deprecated_at": null
26 }
27 ]
28 }
29 },
30 {
31 "id": 202,
32 "resource": "LegacyReport",
33 "action": "Get",
34 "created_at": "2025-11-01T00:00:00.000Z",
35 "updated_at": "2026-05-01T00:00:00.000Z",
36 "deprecated_at": "2026-09-01T00:00:00.000Z",
37 "entrypoints": {
38 "rest": [],
39 "graphql": []
40 }
41 },
42 {
43 "id": 203,
44 "resource": "Organisation.Permission",
45 "action": "List",
46 "created_at": "2026-02-15T00:00:00.000Z",
47 "updated_at": "2026-02-15T00:00:00.000Z",
48 "deprecated_at": null,
49 "entrypoints": {
50 "rest": [
51 {
52 "method": "GET",
53 "path": "/api/v1/organisation/:orgId/permission",
54 "created_at": "2026-02-15T00:00:00.000Z",
55 "updated_at": "2026-02-15T00:00:00.000Z",
56 "deprecated_at": null
57 }
58 ],
59 "graphql": []
60 }
61 }
62]

A permission with a non-null deprecated_at timestamp is end-of-life. It still appears in the catalog so that existing roles keep working, but you can’t add it to new or updated roles.

Every endpoint’s reference page shows its required permission in a Required permissions callout. Select Copy JSON in the callout to copy the permission pair as JSON, ready to paste into the permissions array used below.

Create a custom role

During the beta, a Workspace can hold at most 3 custom roles. To request beta access, contact your Customer Success Manager.

Create a role by giving it a unique name and the set of permissions it grants. List only what you want to grant: anything you leave out is denied.

POST
/api/v1/organisation/:orgId/role
1curl -X POST https://cdn.emnify.net/api/v1/organisation/orgId/role \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Procurement",
6 "description": "Orders SIMs and registers them into the Workspace. No device operations, reports, or billing.",
7 "permissions": [
8 {
9 "resource": "Sim",
10 "action": "List"
11 },
12 {
13 "resource": "Sim.Event",
14 "action": "List"
15 },
16 {
17 "resource": "Event.Type",
18 "action": "List"
19 },
20 {
21 "resource": "Operator",
22 "action": "List"
23 },
24 {
25 "resource": "SimBatch.Bic",
26 "action": "Get"
27 },
28 {
29 "resource": "SimBatch.Bic",
30 "action": "Add"
31 },
32 {
33 "resource": "Endpoint",
34 "action": "Create"
35 },
36 {
37 "resource": "Organisation.Billing.Settings",
38 "action": "Get"
39 },
40 {
41 "resource": "TariffProfile",
42 "action": "List"
43 },
44 {
45 "resource": "ServiceProfile",
46 "action": "List"
47 },
48 {
49 "resource": "IpAddressSpace",
50 "action": "List"
51 },
52 {
53 "resource": "Tag",
54 "action": "List"
55 },
56 {
57 "resource": "Shop.Order",
58 "action": "Create"
59 },
60 {
61 "resource": "Shop.Order.Calculation",
62 "action": "Get"
63 },
64 {
65 "resource": "Shop.Product",
66 "action": "List"
67 },
68 {
69 "resource": "PaymentOption",
70 "action": "List"
71 },
72 {
73 "resource": "ShippingOption.Country",
74 "action": "List"
75 },
76 {
77 "resource": "Organisation.Contact",
78 "action": "List"
79 },
80 {
81 "resource": "Shop.Order",
82 "action": "List"
83 },
84 {
85 "resource": "Shop.Order.Invoice",
86 "action": "Get"
87 },
88 {
89 "resource": "Shop.Order.Item.Artifact",
90 "action": "Get"
91 }
92 ]
93}'

The response is 201 Created with the new role and its resolved permission list:

Response
1{
2 "id": 102,
3 "name": "Procurement",
4 "name_translation_key": null,
5 "description": "Orders SIMs and registers them into the Workspace. No device operations, reports, or billing.",
6 "description_translation_key": null,
7 "user_count": 0,
8 "type": "custom",
9 "is_system_role": false
10}

Instead of resource and action pairs, you can pass numeric permission IDs from the catalog as permission_ids. The two fields are mutually exclusive: supplying both returns 400 Bad Request.

Constraints:

  • Role names must be unique within the Workspace and 2 to 45 characters.
  • Role names accept letters, digits, spaces, and _, -, &, and '. Any other character returns 400 Bad Request.
  • A Workspace can have at most 50 custom roles.

Update a role’s permissions

Update a custom role with a partial PATCH: only the fields you send change.

Sending permissions (or permission_ids) replaces the role’s existing permission list. Include every permission the role should keep, not only the ones you’re adding.

PATCH
/api/v1/organisation/:orgId/role/:roleId
1curl -X PATCH https://cdn.emnify.net/api/v1/organisation/my/role/12 \
2 -H "Authorization: Bearer <token>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "name": "Fleet operator v2",
6 "permission_ids": [
7 2,
8 3,
9 5,
10 7
11 ]
12}'
Response
1{
2 "id": 102,
3 "name": "Fleet operator v2",
4 "name_translation_key": null,
5 "description": "Updated scope after the Q3 review.",
6 "description_translation_key": null,
7 "user_count": 2,
8 "type": "custom",
9 "is_system_role": false,
10 "permissions": [
11 {
12 "id": 2,
13 "resource": "Endpoint",
14 "action": "List"
15 },
16 {
17 "id": 3,
18 "resource": "Endpoint",
19 "action": "Create"
20 },
21 {
22 "id": 4,
23 "resource": "Endpoint",
24 "action": "Delete"
25 },
26 {
27 "id": 5,
28 "resource": "ServicePolicy",
29 "action": "List"
30 }
31 ]
32}

System roles can’t be modified or deleted. To retire a custom role, delete it once no users are assigned to it:

DELETE
/api/v1/organisation/:orgId/role/:roleId
1curl -X DELETE https://cdn.emnify.net/api/v1/organisation/my/role/12 \
2 -H "Authorization: Bearer <token>"

Assign a role to a user

List your roles with their IDs first, if you don’t know them:

GET
/api/v1/organisation/:orgId/role
1curl https://cdn.emnify.net/api/v1/organisation/my/role \
2 -H "Authorization: Bearer <token>"
Response
1[
2 {
3 "id": 1,
4 "name": "Administrator",
5 "name_translation_key": "user_role_administrator_name",
6 "description": "Full access to all organization features and settings.",
7 "description_translation_key": "user_role_administrator_description",
8 "user_count": 4,
9 "type": "system",
10 "is_system_role": true
11 },
12 {
13 "id": 2,
14 "name": "User",
15 "name_translation_key": "user_role_user_name",
16 "description": "Partial write access.",
17 "description_translation_key": "user_role_user_description",
18 "user_count": 12,
19 "type": "system",
20 "is_system_role": true
21 },
22 {
23 "id": 3,
24 "name": "Observer",
25 "name_translation_key": "user_role_observer_name",
26 "description": "Read-only access.",
27 "description_translation_key": "user_role_observer_description",
28 "user_count": 3,
29 "type": "system",
30 "is_system_role": true
31 },
32 {
33 "id": 101,
34 "name": "Fleet operator",
35 "name_translation_key": null,
36 "description": "Can manage endpoints and SIMs but not billing.",
37 "description_translation_key": null,
38 "user_count": 2,
39 "type": "custom",
40 "is_system_role": false
41 }
42]

Then assign a role to a user by ID:

PUT
/api/v1/user/:user_id/role/:role_id
1curl -X PUT https://cdn.emnify.net/api/v1/user/1.1/role/1.1 \
2 -H "Authorization: Bearer <token>"

A successful assignment returns 204 No Content. To remove a role from a user, send DELETE to the same path. A user always keeps at least one role: removing the last remaining role returns 409 Conflict.

Check your own permissions

To verify what your token can do, list the permissions granted by all of your roles in the current Workspace:

GET
/api/v1/user/my/permission
1curl https://cdn.emnify.net/api/v1/user/my/permission \
2 -H "Authorization: Bearer <token>"
Response
1[
2 {
3 "id": 2,
4 "resource": "Endpoint",
5 "action": "List"
6 },
7 {
8 "id": 3,
9 "resource": "Endpoint",
10 "action": "Create"
11 },
12 {
13 "id": 4,
14 "resource": "Endpoint",
15 "action": "Delete"
16 },
17 {
18 "id": 5,
19 "resource": "ServicePolicy",
20 "action": "List"
21 }
22]

Troubleshooting

ResponseCauseFix
400 Bad RequestThe request includes both permissions and permission_ids.Send only one of the two fields.
400 Bad RequestA permission isn’t available to your Workspace type, for example Permission(s) not allowed for this organisation type.Remove that pair from the request. Use the permission catalog to see what your Workspace can assign.
403 ForbiddenYour role doesn’t include the required permission.See Permission errors.
409 ConflictA role with this name already exists, the user already holds the role, or you removed a user’s last role.Rename the role, or adjust the assignment.
422 Unprocessable EntityYou modified a system role, deleted a role that’s still assigned, reached the custom role limit, or referenced a deprecated permission.Target a custom role, unassign users first, or remove the deprecated permission.

For how permissions work and which permissions each system role includes, see Permissions. For ready-made permission sets covering three common jobs, see Role templates.

Role changes raise system events, so you can audit who created, edited, or deleted a custom role, and when a user’s role changed. See User management events.