Get your effective project permissions
Return your relation on one project and every permission you hold there, in one call. Use it to set up a project screen once, for example to hide controls a user can't use.
The response is a fixed object with two keys, relation and permission_grants. See the effective permissions object. It doesn't take ?fields= or ?expand=.
relationis the role granted to you directly on the project:admin,contributor,commenter,guest, or a custom role's slug. It isnullwhen you hold no grant on the project itself, for example when your access comes only from your workspace role or a teamspace.permission_grantscovers the resource types that live in a project, such asproject,workitem,cycle,module, andpage, sorted. Each entry is<resource_type>:<action>. A permission you hold only under a condition appears once per condition, with the condition as a suffix, for exampleworkitem:delete+creator. Permissions you don't hold are left out.
The permissions come from the same check as Check a permission, run against the project, so they include what you inherit from your workspace role. relation doesn't.
Every answer is about the caller. Any member of the workspace can call this endpoint, guests included. You don't need to be a member of the project. Plane doesn't check that the project exists: an id or identifier that matches no project in the workspace still returns 200, with relation set to null.
Path Parameters
slug:requiredstringThe workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.
project_id:requiredstringThe project to read. Accepts the project UUID or its bare identifier, for example ENG.
Scopes
workspaces.permissions:read. The global read scope doesn't satisfy this endpoint.
Errors
| Status | Code | Cause |
|---|---|---|
401 | unauthorized | Missing or invalid credentials. |
403 | forbidden | You aren't a member of the workspace, or your token scope doesn't allow this. |
404 | not_found | No such workspace. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
curl -X GET \
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/permissions/me/" \
-H "X-Api-Key: $PLANE_API_KEY"import requests
response = requests.get(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/permissions/me/",
headers={"X-Api-Key": "your-api-key"},
)
print(response.json())const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/permissions/me/",
{
method: "GET",
headers: {
"X-Api-Key": "your-api-key",
},
},
);
const data = await response.json();{
"relation": "contributor",
"permission_grants": [
"cycle:create",
"cycle:delete+creator",
"cycle:edit+creator",
"cycle:view",
"module:view",
"project:react",
"project:view",
"workitem:archive",
"workitem:assign",
"workitem:create",
"workitem:delete+creator",
"workitem:edit",
"workitem:view"
]
}
