Skip to main content

Roles

6 API calls in this section.

List Roles​

Platform & Access / Roles
GET/roles

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

user_access:system or manage:roles:system to list both scopes. manage:user_access:tenant permits tenant role definitions only. Other callers receive 403. A tenant caller explicitly requesting scope=system receives 403.

Parameters

scope (system/tenant), search, page (default 1), limit (default 10), language. Filtering happens in SQL before pagination and counting; total describes the same roles as the returned page. Each role includes permissions [{id,name}]. Response remains {success:true,message,roles,total,page,limit}.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

scopeOptionalstring

Filter roles by scope (Optional, values: 'system', 'tenant')

searchOptionalstring

Search roles by name or description (Optional)

pageOptionalstring

Page number for pagination (Optional, default: 1)

Example: 1

limitOptionalstring

Number of records per page (Optional, default: 10)

Example: 10

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/roles?language=en&scope=&page=1&limit=10&search=" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Roles retrieved successfully",4  "roles": [5    {6      "id": "role-001",7      "name": "System Admin",8      "description": "System administrator with full access",9      "scope": "system",10      "created_at": "2023-01-01T00:00:00Z",11      "updated_at": "2023-01-01T00:00:00Z"12    },13    {14      "id": "role-002",15      "name": "System Auditor",16      "description": "Read-only access to system resources",17      "scope": "system",18      "created_at": "2023-01-01T00:00:00Z",19      "updated_at": "2023-01-01T00:00:00Z"20    }21  ],22  "total": 2,23  "page": 1,24  "limit": 1025}

Create Role​

Platform & Access / Roles
POST/roles

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

roles:system. Both system and tenant role definitions are globally shared; tenant-scoped user-access permission does not allow editing these definitions.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
nameRequiredstring

(required non-empty string)

descriptionOptionalstring

(optional string). Duplicate name/scope returns 409. Success remains 201 {success:true,message,role}.

scopeRequiredstring

(required system/tenant)

Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/roles?language=en" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "name": "example_role",6  "description": "Example role description",7  "scope": "tenant"8}'

Response examples

201Success Response
Response body
json
1{2  "success": true,3  "message": "Role created successfully",4  "role": {5    "id": "new-role-uuid",6    "name": "example_role",7    "description": "Example role description",8    "scope": "tenant",9    "created_at": "2023-01-01T00:00:00Z",10    "updated_at": "2023-01-01T00:00:00Z"11  }12}

Update Role​

Platform & Access / Roles
PUT/roles/:roleId

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

roles:system. Both system and tenant role definitions are globally shared; tenant-scoped user-access permission does not allow editing these definitions.

role ID. Body: name and/or description. Role scope is immutable. Unknown role: 404. Duplicate name/scope: 409. Success remains 200 {success:true,message,role}.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Path parameters

ParameterTypeDescription
roleIdRequiredstring

UUID of the role to update (Required)

Example: role-uuid

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
namestring—
descriptionstring—
Staging
Request
curl
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/roles/${ROLEID}?language=en" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "name": "updated_role_name",6  "description": "Updated role description"7}'

Response examples

200Success Response
Response body
json
1{2  "success": true,3  "message": "Role updated successfully",4  "role": {5    "id": "role-uuid",6    "name": "updated_role_name",7    "description": "Updated role description",8    "scope": "system",9    "created_at": "2023-01-01T00:00:00Z",10    "updated_at": "2023-01-01T00:00:00Z"11  }12}

Delete Role​

Platform & Access / Roles
DELETE/roles/:roleId

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

roles:system. Both system and tenant role definitions are globally shared; tenant-scoped user-access permission does not allow editing these definitions.

Record removal is blocked by the preservation policy. Unauthorized callers receive 403. Authorized callers receive 409 rbac_preservation_conflict. No role, permission assignment, user assignment, or dependent record is deleted. There is no success response while this policy is active.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Path parameters

ParameterTypeDescription
roleIdRequiredstring

UUID of the role to delete (Required)

Example: role-uuid

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/roles/${ROLEID}?language=en" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

403rbac_forbidden
Response body
json
1{2  "success": false,3  "code": "rbac_forbidden",4  "message": "You do not have permission to perform this action."5}

Assign Permission to Role​

Platform & Access / Roles
POST/roles/:roleId/permissions

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

roles:system. Both system and tenant role definitions are globally shared; tenant-scoped user-access permission does not allow editing these definitions.

{"permission_ids":["permission-uuid", "another-permission-uuid"]}. This is the complete desired permission set, not a single permission_id. All IDs must exist and every permission scope must match the role scope. Duplicate IDs are normalized. Existing assignments omitted from the array produce 409 rbac_preservation_conflict before any write; no removals occur. An unchanged set succeeds with an empty role_permission array. New permissions are inserted in one batch; duplicate assignments are ignored using the existing unique constraint. Authorization uses middleware permissions, and request auditing uses the existing middleware. Non-array or empty permission_ids returns 400; unknown permission IDs return 404. Success: 201 {success:true,message,role_permission:[newlyInsertedAssignments]}.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Path parameters

ParameterTypeDescription
roleIdRequiredstring

UUID of the role to assign the permission to (Required)

Example: role-uuid

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
permission_idsarray<string>—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/roles/${ROLEID}/permissions?language=en" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "permission_ids": [6    "{{permission_id}}"7  ]8}'

Replace {{placeholders}} with your own values before sending.

Response examples

201Success
Response body
json
1{2  "success": true,3  "message": "Permission assigned to role successfully",4  "role_permission": []5}

Remove Permission from Role​

Platform & Access / Roles
DELETE/roles/:roleId/permissions/:permissionId

authenticated JWT or API key. API keys inherit their owner’s permissions; the key’s system/tenant scope remains a ceiling. The api_keys.permissions=[] field is not reinterpreted. The deprecated is_system_admin flag and role names do not authorize these operations.

Errors use {success:false, code, message}; message is localized (en/ar/fa/ku). 403: rbac_forbidden or rbac_invalid_scope. 409: rbac_preservation_conflict, role_already_exists, or the existing last-administrator protection where applicable. Unexpected database errors return 500 with a safe localized message.

Requires manage

roles:system. Both system and tenant role definitions are globally shared; tenant-scoped user-access permission does not allow editing these definitions.

Record removal is blocked by the preservation policy. Unauthorized callers receive 403. Authorized callers receive 409 rbac_preservation_conflict. No role, permission assignment, user assignment, or dependent record is deleted. There is no success response while this policy is active.

Frontend integration

gate controls using the documented permission names and scope. Display localized message for failures; branch on code/status, never message. Handle 403 as denied access and 409 as a conflict requiring correction. No navigation action is added.

Path parameters

ParameterTypeDescription
roleIdRequiredstring

UUID of the role to remove the permission from (Required)

Example: role-uuid

permissionIdRequiredstring

UUID of the permission to remove (Required)

Example: permission-uuid

Query parameters

ParameterTypeDescription
languageOptionalstring

Language code for response localization (Optional, default: en)

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/roles/${ROLEID}/permissions/${PERMISSIONID}?language=en" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

403rbac_forbidden
Response body
json
1{2  "success": false,3  "code": "rbac_forbidden",4  "message": "You do not have permission to perform this action."5}