# Change asset admin roles

Source: https://docs.settlemint.com/docs/developer-guides/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 [user guide](/docs/user-guides/asset-servicing/change-asset-admin-roles).

## 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/developer-guides/api-integration/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 set of administrators with specific roles:

| 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/developer-guides/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:

    ```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 role assignments. Each role contains an array of accounts with that role.
  </Step>

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

    Grant one or more roles to a wallet address 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]

    Assign multiple roles to one wallet in a single transaction:

    ```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]

    Grant the same role to multiple wallets:

    ```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 multiple roles to multiple addresses in a single transaction. Use separate requests for each address
      or each role combination.
    </Callout>
  </Step>

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

    Remove one or more roles from a wallet address:

    ```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]

    Remove multiple roles from one wallet in a single transaction:

    ```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]

    Revoke the same role from multiple wallets:

    ```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]

    Confirm role changes by fetching updated asset details:

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

    The response shows all current role assignments in the `accessControl` field. Verify the changes were applied correctly.
  </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 many 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 |

\*Use either `account` + `roles` OR `accounts` + `role`

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

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

## Response fields [#response-fields]

| 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`. Do not include both shapes in the same request.
* Repeated accounts in one request are deduplicated before the platform queues the blockchain transaction.
* Revoke requests for non-admin roles do not affect the asset's permission-management role.
* When a request revokes multiple roles from the caller, the platform orders the `admin` revoke last so the caller can still complete the remaining role changes in 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/developer-guides/platform-setup/change-admin-roles) - Manage platform-level system roles
