Consent and delegation

Delegated User Management v2 API

Lets trusted people at customer and partner organizations manage their own users' access. DMv2 holds organizations, users, applications, permissions, access roles, admin roles, admin scopes and invitations. It is API-only: everything goes through the Correlation Layer API.

https://{tenant-host}/dm/correlation/apiaudience correlation-layer111 operations
Last checked against a live tenant: 28 October 2026checked live called on a tenantfrom source read in the service codenot confirmed not confirmed

When to use it

  • Build a custom admin portal where partner admins invite and manage their own users.
  • Provision organizations, access roles and permissions from a backend or a pipeline.
  • Read a user's organizations and access roles to make an authorization decision.

Connect

Base URL
https://{tenant-host}/dm/correlation/api
Token
POST https://{tenant-host}/oauth/v1/token with grant_type=client_credentials. The client ID and secret go in the form body.checked live
Client to create
Access admin → Web clients → a dedicated client with the grant type Client credentials. Not an API client: those are only for Access's own configuration API.checked live
Default audiences
add correlation-layer. A client with it wrote to DMv2 on a tenant; the tenant's own DMv2 clients have no audience at all. A token with no audience was refused with 401; a token with another service's audience got 403 (scope missing), not 401.not confirmed
Default scopes
correlation:<object>:<get|post|patch|put|delete> for each object you touch, e.g. correlation:role:get. Use only the scopes Access defines on your tenant (Access admin → Scopes). Tenants can define a subset: one checked defines 28 and none for admin roles, admin scopes, validation schemas, custom objects or search.checked live
Scope length
The full spec set is about 1,500 characters joined with spaces. Access fails to issue a token past 1024. Split the scopes over two clients, or put some under Additional scopes and ask for them with scope= on the token request.checked live
Whose rights apply
With a client-credentials token DMv2 acts as the client and applies no delegation. With a signed-in admin's token it applies that admin's admin roles and scopes.not confirmed
curl -s https://{tenant-host}/oauth/v1/token \
  -d grant_type=client_credentials \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET

curl -s "https://{tenant-host}/dm/correlation/api/v1/roles?pageSize=5&pageNumber=1" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Operations

Open an operation to see its parameters and code, and send it to your tenant. The token needs the listed scope. The credential operations (sign-ins, authenticators, one-time codes, temporary password) name correlation:user:credential:* scopes that many tenants don't define.

Connect to your tenant

Then open any operation below and send it.

Sends grant_type=client_credentials to https://{tenant-host}/oauth/v1/token through this site's server. The secret and token stay in this tab only; host and client ID are remembered.

What trips people up

Lists have no totals

not confirmed

Lists answer {"content": [...], "pageSize": n, "pageNumber": n}. Read content, not items. Page with pageSize (at most 100) and pageNumber; the last page is empty or shorter than pageSize.

A service client bypasses delegation

not confirmed

A client-credentials token can create, change and delete anything its scopes allow, in any organization. Check who may do what before you call, keep your own audit of the real person, and guard the secret like a DMv2 root credential. correlation:admin is not needed.

Role dates are set on assignment only

not confirmed

startDate / endDate are taken when a role is assigned. To change an end date, remove the role (POST /users/{id}/roles/remove) and assign it again. Dates in the past are refused.

Ended assignments are still returned

not confirmed

DMv2 stores validity dates but doesn't hide ended roles or memberships. Filter on the dates yourself. The activeRoles / activeMemberships parameters may help, but their effect isn't verified.

GET /users/{id}/roles doesn't say where a role is held

not confirmed

Pass organizationId and ask per organization. A role can be assigned in an organization the user isn't a member of.

Offer a role from the root down

not confirmed

A role is only available where its parent organization has it. Assigning it directly at a child fails with "not available to organization". POST /organizations/{root}/roles with includeSubOrganizations: true.

There is no move user

not confirmed

Add the user to the new organization, re-read, then remove them from the old one. Removing a user from an organization drops all their relationships there, member and admin. A user with no organization lands in the system "orphan" organization.

Admin-role writes need scopes tenants may lack

not confirmed

Assigning admin roles from a service client needs correlation:admin-role:post|patch|delete. Many tenants define none; then those calls fail with 403.

The root organization has type admin-system-root

not confirmed

Use it as parentId for top-level organizations. Find it with GET /v1/organizations rather than hard-coding an id.

Errors

Errors carry status (a name), code (the HTTP status) and message. The spec also lists 408 and 503 on every operation.

401UNAUTHENTICATEDNo token, an expired one, or one DMv2 doesn't accept (seen with a token that had no audience).
403PERMISSION_DENIED"Forbidden resource": the token lacks the operation's scope, or the admin's delegation doesn't cover the object.
404No object with this id, e.g. after a delete.
408The service timed out. Read back before retrying a write.

When a call fails

ReplyMeansWhat to change
The service answers 401The token lacks this service's audience, or it expired.Add the audience to the client's Default audiences (Access admin → Web clients → the client), then get a new token.
The service answers 403 and the token has the audienceA scope the operation needs is missing.Add one of the operation's scopes to the client's Default scopes. Use the scope names your tenant lists under Access admin → Scopes.
Token endpoint: 401 invalid_clientUnknown client ID or wrong secret.Check the client ID and paste the secret again.
Token endpoint: 400 unauthorized_clientThe client may not use client credentials.Add the grant type Client credentials to the web client.
Token endpoint: 400 invalid_request about an audienceYou asked for an audience the client doesn't have.Add it to Default audiences, or stop asking for it.
Token endpoint: 500 right after scopes were addedThe client's Default scopes, joined with spaces, are over about 1024 characters.Move scopes to Additional scopes and request them per call, or split the work over two clients.
{"code":"not_found","message":"The requested location was not found"}That service isn't deployed on this tenant.Nothing to change in the client. Ask whoever runs the tenant.

Two kinds of client exist in Access. Service APIs like this one take a web client with the Client credentials grant. Access's own configuration API takes an API client: a web client sent there gets 401 invalid_credentials.