# Change asset admin roles

Source: https://docs.settlemint.com/docs/developers/asset-servicing/change-asset-admin-roles
Grant or revoke token-level administrator roles for specific assets via API.



Asset administrator roles control who can operate one token after issuance. This API guide covers grant and revoke requests for token-level roles only. These requests do not change platform-wide system roles or the asset's ownership model. Use these endpoints when you need repeatable role provisioning for operations teams, custodians, supply managers, governance operators, or emergency responders.

<Mermaid
  chart="`
flowchart TD
Operator[&#x22;Asset administrator&#x22;] --> API[&#x22;DALP asset role API&#x22;]
API --> Asset[&#x22;Target asset&#x22;]
API --> Wallet[&#x22;Target wallet&#x22;]
API --> Roles[&#x22;Token-specific roles&#x22;]
Roles --> Supply[&#x22;Supply Management&#x22;]
Roles --> Custodian[&#x22;Custodian&#x22;]
Roles --> Emergency[&#x22;Emergency&#x22;]
Roles --> AssetOps[&#x22;Asset Operator&#x22;]
`"
/>

For the web interface approach, see the [operator user guide](/docs/operators/asset-servicing/change-asset-admin-roles). The sections below cover the API request shape, batch options, and what to verify after each change.

## Prerequisites [#prerequisites]

* Platform URL, such as `https://your-platform.example.com`
* API key from a user with the `admin` role on the target asset. See [Getting Started](/docs/api-reference/reference/getting-started) for API key setup.
* Wallet verification when the platform requires it for transaction signing, such as pincode, secret code, or OTP.
* Asset contract address for the asset to modify.
* Target wallet address, or addresses, for the role change.

## When to change asset admin roles [#when-to-change-asset-admin-roles]

### Common scenarios [#common-scenarios]

* Assign operators after asset creation.
* Give an existing operator another role when their responsibilities expand.
* Remove permissions when an operator no longer needs them.
* Transfer responsibilities between operators after a team change.
* Include role management in provisioning workflows.

### Security considerations [#security-considerations]

* Grant only the roles each operator needs.
* Remove roles when responsibilities end.
* Record the business reason for each role change.
* Coordinate the timing with affected operators.

## About asset admin roles [#about-asset-admin-roles]

Each asset has its own administrator set. Roles define what each administrator can do on that asset.

| Role               | Description                                               | Common use cases                                        |
| ------------------ | --------------------------------------------------------- | ------------------------------------------------------- |
| `admin`            | Permission management for this asset                      | Manage other administrators' roles and permissions      |
| `custodian`        | Freeze addresses, force transfers, and asset recovery     | Custody/operations teams handling interventions         |
| `emergency`        | Pause, unpause, and ERC20 recovery functions              | Incident response team, post-deploy unpausing           |
| `governance`       | Asset policy, verification, and compliance settings       | Team tuning compliance modules or governance parameters |
| `supplyManagement` | Mint and burn permissions via `/api/token/{address}/mint` | Operators issuing, redeeming, or retiring supply        |

<Callout type="info" title="Asset vs platform roles">
  Asset roles are specific to individual assets. Each asset has its own access control. Platform system roles (like
  `tokenManager`) control platform-wide capabilities. See [Change Admin
  Roles](/docs/developers/platform-setup/change-admin-roles) for system roles.
</Callout>

## Changing roles [#changing-roles]

<Steps>
  <Step>
    ### Get asset details [#get-asset-details]

    Query the asset to review current role assignments before making any changes. This step confirms who holds each role on the token before you submit a change.

    ```bash
    curl -X GET "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220" \
      -H "X-Api-Key: YOUR_API_KEY"
    ```

    <Callout type="info" title="Asset address in path">
      The asset contract address is part of the URL path: `/api/token/{assetAddress}`
    </Callout>

    **Response (relevant fields):**

    ```json
    {
      "id": "0x9459D52E60edBD3178f00F9055f6C117a21b4220",
      "name": "Example Asset",
      "symbol": "EXA",
      "decimals": 18,
      "accessControl": {
        "id": "0x1234567890AbCdEf1234567890AbCdEf12345678",
        "admin": [{ "id": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }],
        "custodian": [],
        "emergency": [],
        "governance": [{ "id": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }],
        "supplyManagement": []
      }
    }
    ```

    Review the `accessControl` field to see current assignments. Each entry contains an array of accounts holding that permission on the asset.
  </Step>

  <Step>
    ### Grant a role [#grant-a-role]

    POST to the grant-role endpoint to assign one or more permissions to a wallet on the asset.

    ```bash
    curl -X POST "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/grant-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "account": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        "roles": ["supplyManagement"],
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```

    **Response:**

    ```json
    {
      "accounts": ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"]
    }
    ```

    #### Grant multiple roles [#grant-multiple-roles]

    To assign more than one permission to one wallet in one transaction, list the roles in the array.

    ```bash
    curl -X POST "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/grant-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "account": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        "roles": ["supplyManagement", "custodian"],
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```

    #### Batch grant to multiple wallets [#batch-grant-to-multiple-wallets]

    To grant the same permission to two or more wallets, send all target addresses in one request using the `accounts` array.

    ```bash
    curl -X POST "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/grant-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "accounts": ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "0x8e5F72f6E5b3B4D1234567890AbCdEf1234567890"],
        "role": "supplyManagement",
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```

    <Callout type="warning" title="Batch limitations">
      You cannot grant several roles to several addresses in one transaction. Use separate requests for each address
      or each role combination.
    </Callout>
  </Step>

  <Step>
    ### Revoke a role [#revoke-a-role]

    Send a DELETE request to the revoke-role endpoint to remove one or more permissions from a wallet.

    ```bash
    curl -X DELETE "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/revoke-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "account": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        "roles": ["supplyManagement"],
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```

    **Response:**

    ```json
    {
      "accounts": ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"]
    }
    ```

    <Callout type="warning" title="Keep one asset admin">
      Revoking `admin` is blocked when the request would remove every current asset administrator. If indexed role data is
      missing or shows no current admin holders, an admin revoke is treated as unsafe and rejected rather than risking an
      unmanageable asset.
    </Callout>

    #### Revoke multiple roles [#revoke-multiple-roles]

    To drop more than one permission from a single wallet in one transaction, list all permissions in the array.

    ```bash
    curl -X DELETE "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/revoke-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "account": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        "roles": ["supplyManagement", "custodian"],
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```

    #### Batch revoke from multiple wallets [#batch-revoke-from-multiple-wallets]

    To clear the same permission from two or more wallets, send all target addresses together using the `accounts` array.

    ```bash
    curl -X DELETE "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220/revoke-role" \
      -H "X-Api-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "accounts": ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "0x8e5F72f6E5b3B4D1234567890AbCdEf1234567890"],
        "role": "supplyManagement",
        "walletVerification": { "secretVerificationCode": "YOUR_PINCODE" }
      }'
    ```
  </Step>

  <Step>
    ### Verify changes [#verify-changes]

    Fetch the asset again to confirm the role changes took effect. The `accessControl` field lists current assignments for every role.

    ```bash
    curl -X GET "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220" \
      -H "X-Api-Key: YOUR_API_KEY"
    ```

    Verify the `accessControl` values in the response match the expected state before closing the provisioning record.
  </Step>
</Steps>

## Request parameters [#request-parameters]

| Parameter            | Type      | Required | Description                                                                |
| -------------------- | --------- | -------- | -------------------------------------------------------------------------- |
| `account`            | string    | Yes\*    | Single wallet address when assigning multiple roles to one account         |
| `accounts`           | string\[] | Yes\*    | One or more wallet addresses when assigning one role to multiple accounts  |
| `role`               | string    | Yes\*    | Single role to grant or revoke with `accounts`                             |
| `roles`              | string\[] | Yes\*    | One or more roles to grant or revoke with `account`                        |
| `walletVerification` | object    | No       | Wallet verification for transaction signing when your platform requires it |

\*Each request uses one shape: either `account` with `roles` for one account receiving multiple permissions, or `accounts` with `role` for multiple accounts receiving one permission. Do not mix the two shapes in a single request.

### Wallet verification object [#wallet-verification-object]

Include `walletVerification` when your platform requires it for the signing account. The platform supports three verification types.

| Field                    | Type   | Description                                    |
| ------------------------ | ------ | ---------------------------------------------- |
| `secretVerificationCode` | string | 6-digit pincode or TOTP code                   |
| `verificationType`       | string | "PINCODE" (default), "SECRET\_CODES", or "OTP" |

## Response fields [#response-fields]

The response contains the wallet addresses that the queued role operation covers. Fetch the asset after blockchain confirmation to check indexed role state.

| Field      | Type  | Description                         |
| ---------- | ----- | ----------------------------------- |
| `accounts` | array | Wallet addresses that were modified |

## Operational notes [#operational-notes]

Send one request shape at a time: `accounts` with one `role`, or one `account` with `roles`. Mixing the two shapes in a single request is not supported.

The platform deduplicates repeated accounts before queuing the blockchain transaction. Revoke requests for non-admin roles do not affect the asset's permission-management role.

When a request revokes multiple permissions from the caller, the platform processes the `admin` revoke last, letting the caller complete the remaining changes within the same transaction. The response lists the wallet addresses included in the queued role operation. Fetch the asset again to confirm indexed role state after blockchain confirmation.

## Best practices [#best-practices]

### Role assignment [#role-assignment]

* Grant only the roles each operator needs.
* Split critical functions across more than one administrator.
* Review role assignments when responsibilities change.
* Record each role change and its business reason.

### Security [#security]

* Limit the `admin` role to trusted operators.
* Separate operational roles from governance roles.
* Keep backup administrators for critical roles.
* Use different wallets for different administrative functions.

### Operations [#operations]

* Assign `supplyManagement` to operators who mint or burn.
* Give `emergency` to the operations team that handles incidents.
* Use `custodian` for transfer management and compliance operations.
* Reserve `governance` for strategic configuration decisions.

## Troubleshooting [#troubleshooting]

| Issue                  | Solution                                                                                                                      |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Permission denied      | Verify you have the `admin` role on this specific asset.                                                                      |
| Asset not found        | Check the asset contract address is correct. Ensure the asset is deployed on this platform.                                   |
| Role not found         | Check the role name matches exactly (case-sensitive). Valid roles: admin, custodian, emergency, governance, supplyManagement. |
| Transaction fails      | Ensure wallet has sufficient gas. Verify PIN/OTP is correct. Check network connectivity.                                      |
| Changes not visible    | Wait for blockchain confirmation. Refresh asset details. Check transaction was successful.                                    |
| Cannot revoke own role | Have another user with the `admin` role to revoke your role if needed.                                                        |

## Related guides [#related-guides]

* [Change Admin Roles](/docs/developers/platform-setup/change-admin-roles) - Manage platform-level system roles
