Change one of an integration's roles
/api/v1/organizations/{id}/oauth-clients/{clientId}/assignments/{assignmentId}Changes the role or window of one of an integration's assignments, under the same rules as giving one. Send If-Match with the assignment's version; a stale one answers 409 assignment.version_mismatch.
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.
Path Parameters
idstring Required clientIdstring Required assignmentIdstring Required Headers
If-MatchOptimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since.
Request body
application/json
role_idstring Required effective_fromstring Optional effective_tostring Optional Responses
application/json
data *AssignmentResponseDto
application/json
error *ApiErrorBodyDto
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.
organization.integrations_disabledForbiddenThe Environment does not let organizations create integrations: <code>organization_integrations_enabled</code> is off, which it is by default. Every route under <code>/api/v1/organizations/{org_id}/oauth-clients</code> answers this until the developer turns it on.
Turn on <strong>Let organizations create integrations</strong> on <strong>Tenant → Authentication → Tokens</strong> and choose <strong>Roles integrations may hold</strong>, or send <code>organization_integrations_enabled: true</code> with <code>organization_integration_role_ids</code> to the Environment's auth settings.
organization.integration_role_not_grantableForbiddenThe role is not one an integration may hold: it is not among the Environment's <strong>Roles integrations may hold</strong>, or it has since gained <code>canopy:organization.manage</code> or <code>canopy:access.manage</code>.
Give a role from <code>GET /api/v1/organizations/{org_id}/oauth-client-roles</code>. To offer another, the developer adds it under <strong>Roles integrations may hold</strong> on <strong>Tenant → Authentication → Tokens</strong>.
assignment.grant_ceilingForbiddenThe caller is an identity (a customer's own administrator, acting with its session token) granting a role it may not: the role carries a permission the caller does not hold at the target node or above. Applies to creating an assignment (the organization's assignments route included), changing an assignment's role, and creating an invitation that carries a role. Console users, API keys, and the organization's own administrator inside its organization are never bounded; removing an assignment never is.
Grant a role whose every permission the caller holds at that node, read the roles the caller may grant from <code>GET /api/v1/organizations/{id}/nodes/{nodeId}/grantable-roles</code> and offer only those, or make the change with your API key.
organization.integration_not_foundNot foundNo integration with that <code>client_id</code> belongs to the organization. A machine client the developer pinned to the organization is not one of its integrations and reads as not found here.
List the organization's integrations (<code>GET /api/v1/organizations/{org_id}/oauth-clients</code>) and use a <code>client_id</code> from there. Manage a developer's client on <code>/api/v1/oauth-clients</code>.
assignment.version_mismatchConflictThe request sent <code>If-Match</code> with a version older than the assignment's current one: somebody changed the assignment since it was read.
Read the assignment again, show the reader what changed, and retry with the current <code>version</code>.
Returned object
curl -X PATCH "https://auth.canopy-io.com/api/v1/organizations/value/oauth-clients/value/assignments/value" \ -H "If-Match: "3"" \ -H "X-API-Key: $CANOPY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "role_id": "string", "effective_from": "string", "effective_to": "string" }'
{ "data": { "id": "string", "identity_id": "string", "oauth_client_id": "string", "application_node_id": "string", "role_id": "string", "role_name": "string", "node_name": "string", "effective_from": "2026-04-20T12:00:00.000Z", "effective_to": "2026-04-20T12:00:00.000Z", "created_at": "2026-04-20T12:00:00.000Z", "updated_at": "2026-04-20T12:00:00.000Z", "version": 0 } }
Tell us how we can improve this guide.