POST /unified/check_permissions
Checks a user’s permissions on a specific resource. Returns the permissions they hold and, if you specify an action, whether that action is allowed.
Authentication
Requires Authorization: Basic {base64_encoded_api_key} and x-account-id: {account_id}. See authentication.
Request Body
| Field | Type | Required | Description |
|---|
user_id | string | Conditional | Provider user ID. At least one of user_id or email is required. When both are provided, user_id takes priority. |
email | string | Conditional | User’s email address. If user_id is absent, the connector resolves the email to a user ID internally. |
resource_id | string | Yes | The resource to check. Accepts a StackOne composite ID (starts with c28xIQ) or a plain provider-native ID. |
action | string | No | The action to check. One of: read, write, comment, delete, export. When provided, the response includes allowed. |
At least one of user_id or email must be present. Omitting both returns a 400 error.
The resource_id field accepts two formats:
Composite ID (starts with c28xIQ): A StackOne-encoded ID that embeds the provider resource ID and optional resource type. The service decodes it automatically.
Plain provider ID: Any other string is treated as a native provider resource ID and passed through as-is. The connector uses its default resource type for the check. Use List Resource Types to discover valid types.
Response
| Field | Type | Present | Description |
|---|
user.id | string | Always | The resolved provider user ID |
user.permissions | string[] | Always | Permissions the user holds on this resource: subset of read, write, comment, delete, export. Empty array if the user has no access. |
resource.type | string | Always | The resolved resource type |
resource.id | string | Always | The decoded provider resource ID |
action | string | Only if requested | Echoes back the action from the request |
allowed | boolean | Only if action was requested | true if the requested action is in user.permissions |
Examples
curl --request POST \
--url 'https://api.stackone.com/unified/check_permissions' \
--header 'authorization: Basic {base64_encoded_api_key}' \
--header 'content-type: application/json' \
--header 'x-account-id: {account_id}' \
--data '{
"user_id": "U08FW4R4N6S",
"resource_id": "c28xIQcnQ6Y2hhbm5lbCxpZDpDMDhHNlFCOTBMVQ==",
"action": "read"
}'
{
"user": { "id": "U08FW4R4N6S", "permissions": ["read", "write", "comment"] },
"resource": { "type": "channel", "id": "C08G6QB90LU" },
"action": "read",
"allowed": true
}
curl --request POST \
--url 'https://api.stackone.com/unified/check_permissions' \
--header 'authorization: Basic {base64_encoded_api_key}' \
--header 'content-type: application/json' \
--header 'x-account-id: {account_id}' \
--data '{
"email": "alice@company.com",
"resource_id": "c28xIQaWQ6MWRhYjN..."
}'
{
"user": { "id": "U08FW4R4N6S", "permissions": ["read"] },
"resource": { "type": "folder", "id": "1dab3..." }
}
No action sent — no allowed field in response.{
"user": { "id": "U08FW4R4N6S", "permissions": [] },
"resource": { "type": "channel", "id": "C08G6QB90LU" },
"action": "write",
"allowed": false
}
A 200 response with empty permissions — not an error.
Permission types
These action values differ from the IamPermissionTypeEnum used in the IAM entity model. The IAM enum also includes create and edit, which are not applicable for resource-level permission checks.
The unified permission model normalizes provider-native roles to five action types:
| Type | Description |
|---|
read | View the resource and its content |
write | Modify the resource |
comment | Add comments or annotations |
delete | Remove the resource |
export | Download or export the resource content |
Which permissions are granted for a given provider role depends on the integration. See the connector’s integration guide for how this provider’s roles map to these types.
Error codes
| Status | Condition |
|---|
| 400 | Missing resource_id, missing both user_id and email, or invalid action enum value |
| 401 | Invalid API key |
| 404 | User not found (email resolution failed) or resource not found |
| 422 | The connected provider does not support check_permissions |
| 429 | Provider rate limit reached — retry with backoff |
| 502 | Provider API error |
Edge cases
| Situation | Behavior |
|---|
| User has no access to the resource | 200 with user.permissions: [] and, when an action is provided, allowed: false |
| Deactivated or suspended user | 200 with user.permissions: [] — provider semantics preserved |
| Resource not found | 404 with "resource not found" |
| User not found (email resolution) | 404 with "user not found" |
Both user_id and email provided | user_id is used; email is ignored |
action is not in the enum | 400 validation error |