Object Records Permission Sets
This document describes API endpoints for managing Object Record Permission Sets. Theirs setup is configurable at Object Class level.
Endpoints for assigning users for Object Record Permission Set of specific Object Record are described in separated document.
Permissions
| Permission | Manageable via Roles | Manageable via other ways | Description |
|---|---|---|---|
| object_class.view | true | view by Object Class or Object Record permission sets | Allows access list |
| object_class.edit_perm_set | false |
Permissions for Object Record Permission Sets can be checked by:
| Context | Endpoint | Location | Available perms |
|---|---|---|---|
| Specific Object Class | GET /api/object-classes/{object_class_id}/ | _meta.permissions | view, edit_perm_set |
References
GET /api/object-classes/object_class_id/record-permission-sets/
Returns list of Object Record Permission Sets for specific Object Class.
Permissions
Requires authentication and object_class.view permission.
Request
- Headers
Content-Type: application/json
Authorization: JWT access_token- Schema
GET /api/object-classes/`object_class_id`/record-permission-sets/Response
| Key | Type | Notes |
|---|---|---|
| limit | int | |
| offset | int | |
| total_count | int | Total number of results visible to the user (based on permissions). |
| filtered_count | int | Number of results visible to the user (based on permissions) with filters applied. |
| next | url | Next page URL (null if there is no next page) |
| previous | url | Previous page URL (null if there is no previous page) |
| results | Array | List of results. Described in the next table. |
Response results array
| Key | Type | Notes |
|---|---|---|
| id | int | |
| name | string | |
| permissions | Object | Complex object containing enabled permissions for resources. |
| mcp_permissions | Array | One entry per MCP Connector associated with the Object Class, describing that connector's granted permissions. See below. |
| created_at | datetime | |
| created_by | user | |
| modified_at | datetime | |
| modified_by | user | |
| _meta | Object | Human-readable labels for referenced entities. See below. |
mcp_permissions array
mcp_permissions is a read-only field (not writable via POST/PATCH). It contains one entry per MCP Connector currently associated with the Object Class (association is managed separately, via MCP Connector Object Classes). Each entry has the following shape:
| Key | Type | Notes |
|---|---|---|
| connector | int | MCP Connector id. Resolve the display name via _meta.labels.connectors["<id>"]["name"]. |
| permissions | Object | Granted permissions for this connector, using the same "resource → list of granted actions" shape as the top-level permissions field (only object_records and tasks). |
Semantics:
- One entry per associated MCP Connector, ordered by connector
id. mcp_permissions[].connectoris always just the id (int); the connector name is provided separately in_meta.labels.connectors.- If a connector is associated with the Object Class but has no saved permissions for this Permission Set, its entry is still returned, with empty lists for every resource (fail-closed). For example:
{ "connector": 7, "permissions": {"object_records": [], "tasks": []} }. - If no MCP Connectors are associated with the Object Class,
mcp_permissionsis an empty list ([]) and_meta.labels.connectorsis an empty object ({}).
_meta
_meta is a read-only block following the existing _meta.labels convention. It maps each connector id referenced in mcp_permissions to its label:
"_meta": {
"labels": {
"connectors": {
"<id>": { "name": <str> }
}
}
}- Successful status
200 OK - Response body schema
{
"limit": <int>,
"offset": <int>,
"filtered_count": <int>,
"total_count": <int>,
"next": <str>,
"previous": <str>,
"results": [
{
"id": <int>,
"name": <str>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
},
"mcp_permissions": [
{
"connector": <int>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
}
}
],
"created_at": <datetime>,
"created_by": <user>,
"modified_at": <datetime>,
"modified_by": <user>,
"_meta": {
"labels": {
"connectors": {
"<id>": {"name": <str>}
}
}
}
}
]
}- Response example
{
"limit": 50,
"offset": 0,
"filtered_count": 1,
"total_count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 12,
"name": "Legal Reviewers",
"permissions": {
"object_records": ["view", "edit"],
"tasks": []
},
"mcp_permissions": [
{
"connector": 3,
"permissions": {
"object_records": [],
"tasks": ["edit"]
}
},
{
"connector": 7,
"permissions": {"object_records": [], "tasks": []}
}
],
"created_at": "2026-08-03T10:00:00Z",
"created_by": <user>,
"modified_at": "2026-08-03T10:00:00Z",
"modified_by": <user>,
"_meta": {
"labels": {
"connectors": {
"3": {"name": "Payroll connector"},
"7": {"name": "Audit connector"}
}
}
}
}
]
}Sorting
Not available. Results are sorted by {id} ascending.
Filtering
Not available.
Errors
| Error | Response code | Message |
|---|---|---|
| Object Class for {object_class_id} not found. | 404 Not found | |
| Insufficient permissions | 403 Forbidden | "detail": "You do not have permission to perform this action." |
POST /api/object-classes/object_class_id/record-permission-sets/
Creates single Object Record Permission Set.
Permissions
Requires authentication and object_class.edit_perm_set permission.
Request
- URL parameters
| Key | Notes |
|---|---|
| object_class_id | Object Class ID |
- Body parameters
| Key | Type | Notes |
|---|---|---|
| name | string | Unique (case insensitive) for the given Object Class. |
| permissions | Object | Optional. Complex object containing configuration for resources' permissions to be enabled. |
Available resources for permissions:
object_recordstasks
object_records, tasks keys contain list of actions. By default, permissions are disabled if not given in request's body.
Valid actions for resources:
| object_records | tasks |
|---|---|
Sent permissions are converted with dependencies described in technical doc.
- Headers
Content-Type: application/json
Authorization: JWT access_token- Schema
POST /api/object-classes/`object_class_id`/record-permission-sets/
{
"name": <str>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
}
}- Request example
{
"name": "PermSet",
"permissions": {
"object_records": ["edit"],
"tasks": ["edit", "create"]
}
}Validations
- name
- Max length: 100
- Unique: for specific Object Class
- Maximum number of Object Record Permission Sets per specific Object Class: 10.
Response
| Key | Type | Notes |
|---|---|---|
| id | int | Automatically generated by the backend. |
| name | string | |
| permissions | Object | Complex object contains saved permissions' configuration. |
| created_at | datetime | |
| created_by | user | |
| modified_at | datetime | |
| modified_by | user |
- Successful status
201 Created - Response body schema
{
"id": <int>,
"name": <str>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
},
"created_at": <datetime>,
"created_by": <user>,
"modified_at": <datetime>,
"modified_by": <user>
}Errors
| Error | Response code | Message |
|---|---|---|
| "name" is missing | 400 Bad Request | "name": [ "This field is required." ] |
| "name" is empty string | 400 Bad Request | "name": [ "This field may not be blank." ] |
| "name" is null | 400 Bad Request | "name": [ "This field may not be null." ] |
| "name" has > 100 chars | 400 Bad Request | "name": [ "Ensure this field has no more than 100 characters." ] |
| "name" is not unique for specific Object Class | 400 Bad Request | "name": [ "This field must be unique." ] |
Given NULL for permissions | 400 Bad Request | "permissions": ["This field may not be null."] |
Given wrong resource name for permissions | 400 Bad Request | "permissions": ["Invalid resource \"{given_wrong_resource_name}\"."] |
Given NULL for resource in permissions | 400 Bad Request | "permissions": {"{resource_name}": ["This field may not be null."] } |
Given wrong value for resource in permissions | 400 Bad Request | "permissions": {"{resource_name}": ["Invalid actions \"{given_wrong_value}\"."] } |
| Max 10 Permission Sets per class exceeded | 400 Bad Request | "detail": "Limit of 10 Object Class Permission Sets has been exceeded.", "error_code": "ERR_LIMIT_EXCEEDED" |
| Object Class with {object_class_id} does not exist | 404 Not found | |
| Insufficient permissions | 403 Forbidden | "detail": "You do not have permission to perform this action." |
PATCH /api/object-classes/object_class_id/record-permission-sets/id/
Updates single Object Record Permission Set.
Permissions
Requires authentication and object_class.edit_perm_set permission.
The endpoint also allows configuring permissions available through MCP Connectors associated with the Object Class.
Request
- URL parameters
| Key | Notes |
|---|---|
| object_class_id | Object Class ID |
| id | Object Record Permission Set ID |
- Body parameters
| Key | Type | Notes |
|---|---|---|
| name | string | Unique (case insensitive) for the given Object Class. Max length = 100 (configurable) |
| permissions | Object | Complex object containing configuration for resources' permissions to be enabled. |
| mcp_permissions | Array | Permissions granted to individual MCP Connectors associated with the Object Class. |
Any parameter not listed above are silently ignored if passed.
Available resource keys for permissions:
object_recordstasks
object_records, tasks keys contain list of actions. All are optional. If some resource is omitted then permissions for it will not be modified.
Valid actions for resources:
| object_records | tasks |
|---|---|
Sent permissions are converted with dependencies described in technical doc.
⚠️ If less actions will be sent than are already in setup, not mentioned actions will be removed if they do not depend on other enabled actions.
For instance:
Current actions:
["view", "edit"]. Sent actions:["view"]. Result actions:["view"].
mcp_permissions
mcp_permissions contains permissions granted to individual MCP Connectors.
Each item has the following structure:
| Key | Type | Notes |
|---|---|---|
| connector | int | ID of an MCP Connector associated with the Object Class. |
| permissions | Object | Permissions available through this connector. |
Available resources and actions in mcp_permissions.permissions are the same as for the main permissions field.
The same permission dependencies are applied to MCP permissions. For example, if an action requires another action, the required action is automatically enabled according to the standard permission dependency rules.
MCP permissions can never exceed permissions granted by the Permission Set itself. After resolving dependencies, every MCP permission must also be present in the corresponding main permissions resource.
For example, given:
{
"permissions": {
"object_records": ["view"]
}
}the following MCP configuration is valid:
{
"mcp_permissions": [
{
"connector": 10,
"permissions": {
"object_records": ["view"]
}
}
]
}but granting an additional action unavailable in the Permission Set is rejected:
{
"mcp_permissions": [
{
"connector": 10,
"permissions": {
"object_records": ["edit"]
}
}
]
}If mcp_permissions is omitted, MCP permissions are not directly modified.
If a connector is included in mcp_permissions, only permissions for that connector are modified. Permissions configured for other MCP Connectors remain unchanged.
Resources omitted from mcp_permissions[].permissions are not modified for that connector.
If main permissions are reduced, existing MCP permissions that would exceed the resulting Permission Set permissions are automatically removed. This applies to all MCP Connectors configured for the Permission Set, including connectors omitted from the request.
For example:
Current configuration:
{
"permissions": {
"object_records": ["view", "edit"]
},
"mcp_permissions": [
{
"connector": 10,
"permissions": {
"object_records": ["view", "edit"]
}
}
]
}Request:
{
"permissions": {
"object_classes": ["view"]
}
}Result:
{
"permissions": {
"object_records": ["view"]
},
"mcp_permissions": [
{
"connector": 10,
"permissions": {
"object_records": ["view"]
}
}
]
}⚠️
mcp_permissionscan only be modified using thisPATCHendpoint.
- Headers
Content-Type: application/json
Authorization: JWT access_token- Schema
PATCH /api/object-classes/`object_class_id`/record-permission-sets/`id`/
{
"name": <str>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
},
"mcp_permissions": [
{
"connector": <int>,
"permissions": {
"object_records": [<str>],
"tasks": [<str>]
}
}
]
}- Request example
{
"name": "PermSet",
"permissions": {
"object_records": ["edit"],
"tasks": ["edit", "create"]
}
}Response
| Key | Type | Notes |
|---|---|---|
| id | int | |
| name | string | |
| permissions | Object | |
| mcp_permissions | Object | Effective permissions for MCP Connectors associated with the Object Class. |
| created_at | datetime | |
| created_by | user | |
| modified_at | datetime | |
| modified_by | user | |
| _meta | Object | Additional labels for identifiers used in the response. |
- Successful status
200 OK - Response body schema:
{
"id": <int>,
"name": <str>,
"permissions": {
"object_records": [<str>, ...],
"tasks": [<str>, ...]
},
"mcp_permissions": [
{
"connector": <int>,
"permissions": {
"object_records": [<str>, ...],
"tasks": [<str>, ...]
}
},
...
],
"created_at": <datetime>,
"created_by": <user>,
"modified_at": <datetime>,
"modified_by": <user>,
"_meta": {
"labels": {
"connectors": {
"<connector_id>": {
"name": <str>
}
}
}
}
}Errors
| Error | Response code | Message |
|---|---|---|
| "name" is empty string | 400 Bad Request | "name": [ "This field may not be blank." ] |
| "name" is null | 400 Bad Request | "name": [ "This field may not be null." ] |
| "name" has > 100 chars | 400 Bad Request | "name": [ "Ensure this field has no more than 100 characters." ] |
| "name" is not unique for specific Object Class | 400 Bad Request | "name": [ "This field must be unique." ] |
Given NULL for permissions | 400 Bad Request | "permissions": ["This field may not be null."] |
Given wrong resource name for permissions | 400 Bad Request | "permissions": ["Invalid resource \"{given_wrong_resource_name}\"."] |
Given NULL for resource in permissions | 400 Bad Request | "permissions": {"{resource_name}": ["This field may not be null."] } |
Given wrong action value for resource in permissions | 400 Bad Request | "permissions": {"{resource_name}": ["Invalid actions \"{given_wrong_value}\"."] } |
Given NULL for mcp_permissions | 400 Bad Request | "mcp_permissions": ["This field may not be null."] |
Missing connector in an mcp_permissions item | 400 Bad Request | "mcp_permissions": [{"connector": ["This field is required."]}] |
Given NULL for connector | 400 Bad Request | "mcp_permissions": [{"connector": ["This field may not be null."]}] |
MCP Connector with given connector ID does not exist | 404 Not Found | Standard not-found response |
| MCP Connector is not associated with the Object Class | 400 Bad Request | "detail": ["Invalid pk \"{id}\" - MCP connector is not associated with this Object Class."] |
| MCP permissions exceed main Permission Set permissions | 400 Bad Request | "Invalid actions \"{actions}\" for \"{resource}\" - exceeds the Permission Set's own grant." |
| Object Class with {object_class_id} does not exist | 404 Not Found | |
| Object Record Permission Set with {id} does not exist | 404 Not Found | |
| Insufficient permissions | 403 Forbidden | "detail": "You do not have permission to perform this action." |
DELETE /api/object-classes/object_class_id/record-permission-sets/id/
Deletes single Object Record Permission Set.
Permissions
Requires authentication and object_class.edit_perm_set permission.
Request
- URL parameters
| Key | Notes |
|---|---|
| object_class_id | Object Class ID |
| id | Object Record Permission Set ID |
- Headers
Content-Type: application/json
Authorization: JWT access_token- Schema
DELETE /api/object-classes/`object_class_id`/record-permission-sets/`id`/Response
- Successful status
204 No Content
Errors
| Error | Response code | Message |
|---|---|---|
| Object Class with "{object_class_id}" does not exist | 404 Not found | |
| Object Record Permission Set with "{id}" does not exist | 404 Not Found | |
| Insufficient permissions | 403 Forbidden | "detail": "You do not have permission to perform this action." |
OPTIONS /api/object-classes/object_class_id/record-permission-sets/
Permissions
Requires authentication only.
Request
- URL parameters
| Key | Notes |
|---|---|
| object_class_id | Object Class ID |
- Headers
Content-Type: application/json
Authorization: JWT access_token- Schema
OPTIONS /api/object-classes/`object_class_id`/record-permission-sets/Response
- Successful status
200 OK - Response body:
{
"list": {
"columns": [
{
"alias": "id",
"type": "int",
"predicates": [],
"sort_ok": false
},
{
"alias": "name",
"type": "string",
"predicates": [],
"sort_ok": false
},
{
"alias": "permissions",
"type": "permissions",
"predicates": [],
"sort_ok": false
},
{
"alias": "mcp_permissions",
"type": "permissions",
"predicates": [],
"sort_ok": false
},
{
"alias": "created_at",
"type": "datetime",
"predicates": [],
"sort_ok": false
},
{
"alias": "created_by",
"type": "user",
"predicates": [],
"sort_ok": false
},
{
"alias": "modified_at",
"type": "datetime",
"predicates": [],
"sort_ok": false
},
{
"alias": "modified_by",
"type": "user",
"predicates": [],
"sort_ok": false
}
]
},
"details": {
"schema": [
{
"alias": "name",
"type": "string",
"required": true,
"validators": [
{
"type": "min_length",
"length": 1
},
{
"type": "max_length",
"length": 100
}
]
},
{
"alias": "permissions",
"type": "permissions",
"required": false,
"schema": [
{
"resource": "object_records",
"actions": [
"view",
"edit",
"delete"
]
},
{
"resource": "tasks",
"actions": [
"view",
"edit",
"delete",
"create",
"complete",
"assign"
]
}
]
},
{
"alias": "mcp_permissions",
"type": "permissions",
"required": false,
"schema": [
{
"resource": "object_records",
"actions": [
"view",
"edit",
"delete"
]
},
{
"resource": "tasks",
"actions": [
"view",
"create",
"edit",
"delete",
"complete",
"assign"
]
}
]
}
]
},
"restrictions": {
"limit_items": 10
}
}Errors
| Error | Response code | Message |
|---|---|---|
Object Class for object_class_id not found. | 404 Not Found |
Not allowed endpoints
GET /api/object-classes/object_class_id/record-permission-sets/id/
Response
- Status
405 Method Not Allowed