# Participant role assignments

Source: https://docs.settlemint.com/docs/api-reference/reference/participant-role-assignments
Read participant role assignments across signing and operations addresses through the DALP Platform API, including the drift signal that flags when on-chain roles do not match.



A participant role assignment shows which access-control roles a participant
holds, broken out by the participant's signing address and operations address.
DALP returns this view at two scopes: system-wide roles for the whole
deployment, and per-asset roles for one token.

Use these endpoints to audit who holds which authority and to confirm that a
participant's granted roles are complete before they act. For the model behind
the roles themselves, see
[Role-based access control](/docs/architects/components/asset-contracts/rbac)
and [Authorization](/docs/compliance-security/security/authorization).

## What the view answers [#what-the-view-answers]

Each item describes one participant's role state across the addresses that can
carry authority. The exact shape depends on whether account abstraction is
enabled for the deployment.

### When account abstraction is enabled [#when-account-abstraction-is-enabled]

* `eoaRoles` lists the roles held on the participant's signing address (the
  externally owned account).
* `smartWalletRoles` lists the roles held on the participant's operations
  address (the smart account used when account abstraction routes the
  operation).
* `missingRoles` lists roles the participant holds on the signing address but
  not on the operations address.
* `drift` is `true` when `missingRoles` is non-empty, meaning at least one role
  the participant holds on the signing address is not present on the operations
  address.

Read `drift` and `missingRoles` together when you reconcile permissions. A
participant can hold a role on the signing address that the operations address
does not carry, so an operation routed through the operations address would not
have it. The view surfaces that gap instead of hiding it behind a single
combined list. The comparison is one-way: it reports signing-address roles that
the operations address is missing, not roles that exist only on the operations
address.

### When account abstraction is disabled [#when-account-abstraction-is-disabled]

In deployments without account abstraction, the view falls back to a consolidated
read of indexed role rows. Every role found for a participant is reported in
`eoaRoles`, while `smartWalletRoles`, `missingRoles`, and `drift` are always
empty or `false` because there is no separate operations address to compare
against. Integrators should treat `eoaRoles` as the complete role set for the
participant in this mode.

## Endpoints [#endpoints]

Both endpoints are frozen v2 collection contracts. They return the standard DALP
collection envelope with `data` for the page of items, `meta` for total count
and facets, and `links` for pagination.

| Endpoint                                               | Scope                                                     |
| ------------------------------------------------------ | --------------------------------------------------------- |
| `GET /api/v2/system/participants/roles`                | Participant role assignments across the whole deployment. |
| `GET /api/v2/tokens/{tokenAddress}/participants/roles` | Participant role assignments for one token.               |

See
[Organization and system scope](/docs/api-reference/reference/organization-system-scope)
for how the active organisation and chain context bound every read.

## Path parameters [#path-parameters]

| Parameter      | Type             | Used by                                    |
| -------------- | ---------------- | ------------------------------------------ |
| `tokenAddress` | Ethereum address | Per-token endpoint. The token to scope to. |

## Item fields [#item-fields]

The two scopes share the same shape, with one difference: the per-token view
also returns `accountAddress` and reports `isContract` per participant, while
the system view always reports `isContract` as `false`.

### Contract rows in the per-token view [#contract-rows-in-the-per-token-view]

The per-token endpoint also returns rows for role-holder accounts that are not
mapped to a participant. These rows have `participantId`, `signingAddress`,
and `operationsAddress` set to `null`, `accountAddress` and `displayName` set
to the role-holder address, and `isContract` set to `true`. They are distinct
from participant rows where `participantId` is `null` because the caller cannot
resolve participant names. In those masked participant rows, `signingAddress`
and `operationsAddress` are still present.

| Field               | Type                     | Description                                                                                                             |
| ------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `participantId`     | string or null           | Participant identifier. `null` for a non-participant contract row, or when the caller cannot resolve participant names. |
| `displayName`       | string                   | Human-readable name. Falls back to the signing address when the caller cannot resolve participant names.                |
| `signingAddress`    | Ethereum address or null | The participant's signing address (externally owned account).                                                           |
| `operationsAddress` | Ethereum address or null | The participant's operations address (smart account), when one is configured.                                           |
| `accountAddress`    | Ethereum address or null | Per-token view only. The address the role rows are read against.                                                        |
| `isContract`        | boolean                  | Whether the listed entry is a contract. Always `false` for the system view.                                             |
| `eoaRoles`          | array of role names      | Roles held on the signing address.                                                                                      |
| `smartWalletRoles`  | array of role names      | Roles held on the operations address.                                                                                   |
| `missingRoles`      | array of role names      | Roles held on the signing address but not on the operations address.                                                    |
| `drift`             | boolean                  | `true` when `missingRoles` is non-empty.                                                                                |

## Role names [#role-names]

The role names returned in `eoaRoles`, `smartWalletRoles`, and `missingRoles`
depend on the scope.

* **System view** uses system roles: `admin`, `auditor`, `systemManager`,
  `tokenManager`, `complianceManager`, `claimPolicyManager`, `claimIssuer`,
  `identityManager`, `feedsManager`, `gasManager`.
* **Per-token view** uses asset roles: `admin`, `custodian`, `emergency`,
  `fundsManager`, `governance`, `saleAdmin`, `supplyManagement`.

## Query the list [#query-the-list]

Both endpoints accept the standard collection query parameters: pagination with
`page[limit]` and `page[offset]`, sorting with `sort`, global search with
`filter[q]`, and per-field filters. The default sort is by `displayName`.

You can filter and build facets on the role arrays and on `drift`. To list
every participant in drift, meaning they hold a role on the signing address that
the operations address does not carry:

```bash
curl --globoff "https://your-platform.example.com/api/v2/system/participants/roles?filter[drift]=true" \
  -H "X-Api-Key: YOUR_DALP_API_KEY"
```

To list participants whose signing address holds a specific system role:

```bash
curl --globoff "https://your-platform.example.com/api/v2/system/participants/roles?filter[eoaRoles]=complianceManager" \
  -H "X-Api-Key: YOUR_DALP_API_KEY"
```

`filter[eoaRoles]` matches the signing address only. When a participant holds a
role on the operations address instead, that grant appears in `smartWalletRoles`
and is not returned by an `eoaRoles` filter. To audit every account that can
exercise a role, check both `eoaRoles` and `smartWalletRoles` rather than
filtering on `eoaRoles` alone.

For the per-token view, supply the token address in the path:

```bash
curl --globoff "https://your-platform.example.com/api/v2/tokens/0xTOKEN/participants/roles?filter[drift]=true" \
  -H "X-Api-Key: YOUR_DALP_API_KEY"
```

The response includes facet counts in `meta` for the filterable role fields and
`drift`, so a client can show how many participants hold each role or are in
drift without making a second call.

## Authorisation [#authorisation]

Reading the system view requires a caller with the roles that govern system
access listing. Reading the per-token view requires read access to that token.
Participant name resolution is gated separately: when the caller cannot resolve
participant names, `participantId` is returned as `null` and `displayName`
falls back to the participant's signing address. The role rows and addresses are
still returned.

## Related [#related]

* [Role-based access control](/docs/architects/components/asset-contracts/rbac)
* [Authorization](/docs/compliance-security/security/authorization)
* [Organization and system scope](/docs/api-reference/reference/organization-system-scope)
* [Request headers](/docs/api-reference/reference/request-headers)
