Skip to main content

Get started with the Management API

This guide walks through your first Management API call. You get a token, send a narrowly filtered read for one user, and read the result. It then explains how to set up safe access for automation.

Before you start​

You need:

  • An environment where the Personalization Service is enabled.
  • A token for that environment that holds the Data: Read (DATA_READ) permission.
  • The ID of a user whose data you want to inspect.

Choose the token type that fits your use case.

Token typeUse it for
Service Account TokenBackend services, scheduled jobs, scripts, and other automation
User Account TokenA person using an administration tool with the permissions of their roles

For automation, always use a Service Account Token.

Get a token​

Service Account Token​

  1. Create a Service Account for this integration in the Mosaic Admin Portal.
  2. Grant it only the permissions the integration needs. For this guide, grant Data: Read.
  3. Exchange the Service Account credentials for an access token.

The steps for creating a Service Account, granting permissions, and requesting a token, including generating a token in the Admin Portal for testing, are described in How to Authenticate a Service Account. Access tokens expire, so automation should request a new token when the current one expires.

User Account Token​

A User Account Token is the access token that the Identity Service issues to a signed-in Mosaic user. The token carries the permissions of that user's roles. See Authentication and Authorization for how these tokens work.

Keep credentials on the server​

A token with Management API permissions can reach the data of every user in the environment. Treat it like any other server credential.

  • Store Service Account secrets and tokens in a secret store, not in source control.
  • Never embed a Service Account secret or Service Account Token in a frontend application, a mobile app, or any end-user client.
  • Use a User Account Token only in trusted administrative tools, where the signed-in person holds the needed permissions.
  • Do not log tokens.

End-user applications use the End-User API with tokens issued to end users.

Send your first request​

The following read lists the key-value entries that one user stored under one key. Narrow filters like this keep a first call small and make it clear which data you are reading.

The operation:

query InspectUserPreferences($input: ListKeyValuesInput!) {
listKeyValues(input: $input) {
nodes {
key
kind
value
owner {
userId
profileId
applicationId
scope
}
}
pageInfo {
hasNextPage
endCursor
}
}
}

The variables, with a user ID of your choice:

{
"input": {
"filter": {
"userId": "11111111-1111-4111-8111-111111111111",
"key": "ui:preferences",
"scope": "USER"
},
"first": 10
}
}

Send both as one JSON request body. Replace <token> with your access token.

curl https://personalization.service.eu.axinom.net/graphql-management \
--request POST \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"query": "query InspectUserPreferences($input: ListKeyValuesInput!) { listKeyValues(input: $input) { nodes { key kind value owner { userId profileId applicationId scope } } pageInfo { hasNextPage endCursor } } }",
"variables": {
"input": {
"filter": {
"userId": "11111111-1111-4111-8111-111111111111",
"key": "ui:preferences",
"scope": "USER"
},
"first": 10
}
}
}'

Read the response​

A successful response contains the matching entries and paging information. The values below are only an illustration of the shape.

{
"data": {
"listKeyValues": {
"nodes": [
{
"key": "ui:preferences",
"kind": "JSON",
"value": { "theme": "dark", "language": "en" },
"owner": {
"userId": "11111111-1111-4111-8111-111111111111",
"profileId": null,
"applicationId": null,
"scope": "USER"
}
}
],
"pageInfo": {
"hasNextPage": false,
"endCursor": "<opaque cursor>"
}
}
}
}
  • nodes contains one entry per stored record that matches the filter. It is empty when the user has no data under the key.
  • owner tells you exactly where each record is stored.
  • pageInfo.hasNextPage tells you whether to request another page. See Paginate with cursors.

Set up least-privilege access for automation​

Create a separate Service Account for each integration and grant only the permissions its operations require.

Integration purposePermission to grant
Reporting, audits, and data inspectionData: Read
Support tools that correct one user's dataData: Read and Data: Write
Maintenance jobs that change data for many usersBulk Data: Write

A few rules of thumb:

  • Start with Data: Read and add permissions only when an integration needs them.
  • Keep Bulk Data: Write separate from Data: Write, because bulk jobs can change data for every user in the environment.
  • Remove permissions that an integration no longer uses.

See Authentication and permissions for the operation-to-permission mapping.

Fix common problems​

SymptomLikely cause
UNAUTHENTICATED errorThe token is missing, invalid, or expired, or it is not a User Account or Service Account Token
FORBIDDEN errorThe token does not hold the permission that the operation needs
BAD_USER_INPUT with reason FILTER_CONSTRAINTThe filter contains ids that contradict the scope. See Filter by owner and scope
Empty nodes with hasNextPage set to trueKeep following endCursor. See Paginate with cursors

See Errors and limits for the full list.

Next steps​

Was this page helpful?