List who holds a permission at a node in the organization
/api/v1/organizations/{id}/nodes/{nodeId}/holdersWho holds the permission at the node now, directly or inherited from a node above it: one row per assignment that grants it, with the identity, the role, where it was granted (granted_at), access_type and the window. The rules are evaluate's, so a disabled role, a closed window or an ended membership in the organization grants nothing and is left out. Supports filtering by q, role_id and access_type, sorting by name, role or access_type, and paging. Requires the same as the node access listing.
Authentication
Authorization Option A JWT access token. Never send alongside X-API-Key: a request carrying both is refused.
X-API-Key Option B API key for management-tier access. Never send alongside an Authorization header: a request carrying both is refused.
production_identities.accessDeveloper ConsoleAccess identities in production Environments. Applies to users only, and only in an Environment marked production: its identities are real end users. API keys and identity principals are exempt.
Path Parameters
idstring Required nodeIdstring Required Query Parameters
pagenumber Optional Page number (1-based)
takenumber Optional Items per page (1-100, default 20)
qstring Optional Search the holders by first name, last name or email.
sort_byenum Optional Sort column. Defaults to `name`, ascending. Ties end on the assignment id.
orderenum Optional Sort direction
permissionstring Required The permission to list holders of, by key.
access_typeenum Optional `direct` for grants made at the node itself, `inherited` for grants made above it.
role_idstring Optional Only grants through this role.
Responses
application/json
items *NodeHolderDto[]pagination *PageMetaDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
Errors
When the request can't be completed, the response body includes a stable error code you can branch on, and a correlation_id (also sent as the X-Correlation-Id header). Quote the correlation id when you contact support: it identifies the exact request in Canopy's logs. A request refused by an authorization check answers 403 with the code authorization.denied, and its data names the denial_reason and the permission checked.
environment.production_identities_forbiddenForbiddenThe Environment is marked production and the caller is a user without production identity access.
Manage these people in the Admin Workspace, or ask an administrator to grant the Production Support role, then retry.
Pagination
This endpoint returns a paginated collection. Use the query parameters below to page through results.
pagenumberPage number (1-indexed). Defaults to 1.
takenumberItems per page (1 to 100). Defaults to 20.
Each response includes an items array alongside a pagination object with item_count, page_count, has_previous_page, and has_next_page fields.
Returned object
curl -X GET "https://auth.canopy-io.com/api/v1/organizations/value/nodes/value/holders?page=0&take=0&q=value&sort_by=name&order=asc&permission=value&access_type=direct&role_id=value" \ -H "X-API-Key: $CANOPY_API_KEY"
{ "items": [ { "identity": { "id": "string", "first_name": "string", "last_name": "string", "name": "string", "email": "string", "avatar_url": "string" }, "role": { "id": "string", "name": "string" }, "assignment_id": "string", "granted_at": { "id": "string", "name": "string" }, "access_type": "direct", "effective_from": "2026-04-20T12:00:00.000Z", "effective_to": "2026-04-20T12:00:00.000Z" } ], "pagination": { "page": 0, "take": 0, "item_count": 0, "page_count": 0, "has_previous_page": false, "has_next_page": false } }
Tell us how we can improve this guide.