# access-control.role-granted.provisional

Source: https://docs.settlemint.com/docs/events/access-control-role-granted-provisional
A role was granted on the access-control manager; the grant is provisional until the indexer reaches the configured reorg depth.



A role was granted on the access-control manager; the grant is provisional until the indexer reaches the configured reorg depth.

## Delivery contract [#delivery-contract]

| Field                           | Value                                           |
| ------------------------------- | ----------------------------------------------- |
| Event type                      | `access-control.role-granted.provisional`       |
| Version                         | `1`                                             |
| Lifecycle state                 | `provisional`                                   |
| Counter-signed receipt required | `false`                                         |
| SDK type                        | `Webhook.AccessControlRoleGrantedProvisionalV1` |

Related references:

* `idxr_access_control_role_member`

## When to consume this event [#when-to-consume-this-event]

Consume `access-control.role-granted.provisional` when your integration needs early notice that an account received a role on an access-control manager.

Use the event to stage permission-aware synchronization, administrative review queues, or audit exports that can tolerate provisional indexing. Do not treat the role membership as final while the observation is still inside the configured reorg depth.

Your consumer must handle a later retraction for the same on-chain observation. Store `evt_id`, `request.idempotency_key` when present, `roleId`, `accountAddress`, `accessManagerAddress`, `chainId`, and `transactionHash`. These values keep retries or replayed deliveries from creating duplicate permission changes downstream.

The payload carries the access manager, grantee account, role identifier, sender, owning system, chain ID, block number, and transaction hash. Treat `accountAddress` and `sender` as personal-data-bearing fields for webhook privacy reviews. If your endpoint is configured for thin payload delivery, do not depend on those fields in the first delivery.

`roleId` is the raw on-chain role identifier. DALP resolves known role identifiers such as `admin`, `systemManager`, `identityManager`, `tokenManager`, and `complianceManager` in indexed access-control views. The webhook payload keeps the raw value.

See [webhook idempotency and on-chain outcome](/docs/events/idempotency-and-on-chain-outcome/) for retry, replay, payload-shape, and provisional-event handling.

## Payload schema [#payload-schema]

```json
{
  "type": "object",
  "properties": {
    "accessManagerAddress": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "accountAddress": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "blockNumber": {
      "type": "string"
    },
    "chainId": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "roleId": {
      "type": "string"
    },
    "sender": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "systemAddress": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$"
    },
    "transactionHash": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{64}$"
    }
  },
  "required": [
    "accessManagerAddress",
    "accountAddress",
    "blockNumber",
    "chainId",
    "roleId",
    "sender",
    "systemAddress",
    "transactionHash"
  ],
  "additionalProperties": false
}
```

## TypeScript SDK example [#typescript-sdk-example]

```typescript
import { verifyWebhook, type Webhook } from "@settlemint/dalp-sdk";

const result = verifyWebhook({
  rawBody,
  headers,
  secret: process.env.DALP_WEBHOOK_SECRET!,
});

if (!result.ok) {
  throw new Error(`Webhook verification failed: ${result.code}`);
}

if (result.event.type === "access-control.role-granted.provisional") {
  const event: Webhook.Event<"access-control.role-granted.provisional"> = result.event;
  console.log(event.payload);
}
```

## curl example [#curl-example]

```bash
curl -X POST https://consumer.example.com/dalp/webhooks \
  -H "content-type: application/json" \
  -H "webhook-id: evt_docs_access_control_role_granted_provisional_001" \
  -H "webhook-timestamp: 1778112000" \
  -H "webhook-signature: v1,docs-example-signature" \
  --data '{"evt_id":"evt_docs_access_control_role_granted_provisional_001","type":"access-control.role-granted.provisional","version":1,"lifecycle_state":"provisional","request":{"idempotency_key":"idem_01JZP7R5W8M9N0P1Q2R3S4T5"},"related":{"idxr_access_control_role_member":"idxr_access_control_role_member_example"},"payload":{"accessManagerAddress":"0x1111111111111111111111111111111111111111","accountAddress":"0x2222222222222222222222222222222222222222","blockNumber":"18445201","chainId":537001,"roleId":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","sender":"0x3333333333333333333333333333333333333333","systemAddress":"0x4444444444444444444444444444444444444444","transactionHash":"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}}'
```

## Version history [#version-history]

* Version `1`: Initial registry entry for `access-control.role-granted.provisional`.

## Deprecation [#deprecation]

This event type is not deprecated.

## Manifest [#manifest]

The machine-readable AsyncAPI entry is published in the [DALP events manifest](/.well-known/dalp-events.json).
