Consent and delegation
Consent management API
Keeps the documents users accept (privacy policy, terms) and the processing purposes they grant, with versions and translations, and records each user's consents in a ledger.
https://{tenant-host}/consent-management/api/v1audience consent-management47 operationsWhen to use it
- Show a user the documents they still have to accept, then record the acceptance.
- Record or revoke a user's consent to a processing purpose, with channel preferences.
- Publish a new version of a document or purpose, or report on consent history.
Connect
- Base URL
https://{tenant-host}/consent-management/api/v1- Token
POST https://{tenant-host}/oauth/v1/tokenwithgrant_type=client_credentials. The client ID and secret go in the form body.checked live- Client to create
- Access admin → Web clients → a client with the grant type Client credentials. Not an API client: those are only for Access's own configuration API.checked live
- Default audiences
- must include
consent-managementchecked live - Default scopes
- The scope each operation lists below. The audience alone gets 403. Some tenants don't define these scopes in Access yet: create them, then add them to the client. Keep the client's scopes, joined with spaces, within 1024 characters.checked live
- Idempotency-Key
- Optional UUID header on grant and revoke calls. Send a fresh one per user decision; reuse it only to retry that decision.from source
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}/consent-management/api/v1/config/documents?pageNumber=0&pageSize=5" \
-H "Authorization: Bearer $ACCESS_TOKEN"Operations
Open an operation to see its parameters and code, and send it to your tenant. Each operation has its own scope. The configuration operations are the same for documents and purposes. The scope of versions-with-locales isn't confirmed.
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
The audience alone gets 403
checked liveA token with consent-management in its audience but without the operation's scope is refused with 403, even for a plain config read. The published spec names no scopes at all: use the ones listed here.
Each id type goes to one place
from sourceIds carry a prefix: DD-/DV-/DL- for documents, PD-/PV-/PL- for purposes. Document consents take DL- ids, purpose consents take PL- ids, and a purpose revoke takes PD- ids.
Only ACTIVE versions accept consent
from sourceA new version starts as DRAFT. Its status follows its dates: effective → ACTIVE, future → SCHEDULED, then SUNSET and ARCHIVED. Recording consent for a localization of any other status fails the whole batch with 400.
Request bodies are strict
from sourceUnknown fields are rejected, and strings or booleans aren't coerced: send true, not "true". The IO consent nodes take other inputs (localizationIds): don't copy them into a REST body.
An Idempotency-Key replays, it doesn't compare
from sourceWithin 24 hours, the same key for the same user returns the stored result without saving anything, even if the body changed. The same key for another user answers 409. Use a fresh UUID for every decision and every operation.
Use - as userId before the user exists
from sourceoutstanding and posture accept - to list what a new user will have to accept. Recording, revoking and importing need a real Identity Store id.
A version PATCH with localizations replaces the list
from sourcelocalizations is the final state: entries you leave out are deleted. For a narrow change use localizationsAdded, localizationsUpdated and localizationsDeleted, never together with localizations.
Posture is current status, the ledger is history
from sourceAsk posture whether a user has consented now. Purpose posture adds UPDATE_AVAILABLE when the purpose changed since the grant: that is not a revocation. The ledger lists stored grants and revocations, newest first.
Paging starts at 0
from sourcepageNumber is 0-based on lists, posture and the ledger. Posture pages default to 10 items, the ledger to 50; both allow at most 100.
Imports save row by row
from sourceImport validation is all-or-nothing, but rows are then saved one at a time. After a failure, resend the same batch with the same consentedAt values: saved rows come back as ALREADY_EXISTS.
Errors
Error bodies carry id (request id), code, message and details. Codes are consent_* strings, so read code as well as the status. An unknown path can answer 403 instead of 404.
| 400 | consent_purpose_revocation_no_prior_consent | Revoke of a purpose the user hasn't granted (or already revoked). |
| 400 | consent_multiple_validation_errors | Several validation errors at once (imports). Each detail carries its own error code. |
| 400 | consent_* | Invalid input, including unknown fields or a localization that isn't ACTIVE. |
| 404 | consent_* | Definition, version or localization not found. |
| 409 | consent_registration_idempotency_key_conflict | The Idempotency-Key was used for another user. |
| 500 | consent_internal_error | Unexpected failure. Quote the id field when you report it. |
When a call fails
| Reply | Means | What to change |
|---|---|---|
| The service answers 401 | The 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 audience | A 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_client | Unknown client ID or wrong secret. | Check the client ID and paste the secret again. |
| Token endpoint: 400 unauthorized_client | The client may not use client credentials. | Add the grant type Client credentials to the web client. |
| Token endpoint: 400 invalid_request about an audience | You 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 added | The 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.