> For the complete documentation index, see [llms.txt](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/policies-workflows/lifecycle-management-notification-templates.md).

# Notifications

### Email Templates Overview

Administrators can customize email notifications sent during Lifecycle Management and Access Request workflows. These emails can include instructions, unique branding, and placeholders for metadata specific to the event (such as entity names, action types, or request details). Each notification type (usage) can have its own customized template.

Notification templates support HTML and CSS. They can include links to external images or you can upload small files to Veza. This document includes steps to configure templates in the Veza UI or the Notification Templates API, and a reference for event types, default templates, and supported placeholders.

{% hint style="info" %}
**Template Management**: You can manage notification templates in the Veza UI (**Lifecycle Management** > **Settings** > **Notifications**) or through the Notification Templates API.
{% endhint %}

{% hint style="info" %}
**Access Reviews Notification Templates**: For access review workflow notifications, see [Access Reviews Notification Templates](/4yItIzMvkpAvMVFAamTf/developers/api/notification-templates.md).
{% endhint %}

### Custom Email Templates

In addition to event-specific templates, you can create **custom email templates** that are not tied to specific lifecycle events. These reusable templates allow you to define notification content once and use it across Send Notification actions and action notification settings. Custom email templates are:

* **Reusable**: Single template for multiple workflows and actions
* **Event-independent**: Not associated with a specific lifecycle event type
* **Flexible**: Can be used in both Send Notification actions and action notification settings (`on_success`/`on_failure`)
* **Standard placeholder support**: Supports all the same placeholders as event-based templates

To create a custom email template:

1. Navigate to **Lifecycle Management** > **Settings** > **Notifications**
2. Click **Create Template**
3. Select **For custom mail** (as opposed to "For event")
4. Define your template name, subject, and body using HTML and placeholders
5. Save the template

To use a custom template, select it when configuring the Send Notification action, or in Action Notification Settings:

* **Send Notification action**: Choose from the "Select Email Template" dropdown when configuring the action
* **Action Notification Settings**: Select the template for `on_success` or `on_failure` email notifications on any action

When you select "Default template" in these dropdowns, the system uses the event-based template appropriate for the event. When you select a custom template, that template is used regardless of the specific event being processed.

{% hint style="info" %}
Custom templates support all standard placeholders documented in the [Placeholders](#placeholders) section. The available values depend on the context in which the template is used (e.g., action notifications have action-related placeholders, event notifications have event-related placeholders).
{% endhint %}

### Default Templates

The system provides built-in templates for all Lifecycle Management and Access Request events. These templates use placeholders that are automatically replaced with actual values when notifications are sent.

**Generic Failure Template**

When specific event templates aren't available or when events fail, the system uses a generic failure template:

**Subject**: `Lifecycle job {{EVENT_TYPE}} has failed`

**Body**:

```html
<html><body>
<br>
<br> Here is the notification that lifecycle job has failed. <br>
Error message: {{EVENT_ERROR_MESSAGE}}<br>
<br>
For reference:
<br> job_id: {{JOB_ID}}<br>
<br> identity_id: {{EVENT_IDENTITY_ID}}
<br> identity_name: {{EVENT_IDENTITY_NAME}}
<br> entity_type: {{ENTITY_TYPE}}
<br> entity_name: {{ENTITY_NAME}}
</body></html>
```

See [Default Template Content](#default-template-content) for all default messages.

**Lifecycle Management Events**

Each template you create is associated with a specific notification event (referred to as `usage` in the API). The following event types are available for Lifecycle Management workflows, organized by functional area:

<details>

<summary>Identity Management Events</summary>

| Event Type                    | API Usage Value                                      | Description                                                   |
| ----------------------------- | ---------------------------------------------------- | ------------------------------------------------------------- |
| Create Identity               | `LIFECYCLE_MANAGEMENT_CREATE_IDENTITY`               | Sent when a new identity/account is created                   |
| Create Identity Failed        | `LIFECYCLE_MANAGEMENT_CREATE_IDENTITY_FAILED`        | Sent when identity creation fails                             |
| Sync Identity                 | `LIFECYCLE_MANAGEMENT_SYNC_IDENTITY`                 | Sent when an identity is synchronized                         |
| Sync Identity Failed          | `LIFECYCLE_MANAGEMENT_SYNC_IDENTITY_FAILED`          | Sent when identity sync fails                                 |
| Delete Identity               | `LIFECYCLE_MANAGEMENT_DELETE_IDENTITY`               | Sent when an identity is deleted                              |
| Delete Identity Failed        | `LIFECYCLE_MANAGEMENT_DELETE_IDENTITY_FAILED`        | Sent when identity deletion fails                             |
| Disable Identity              | `LIFECYCLE_MANAGEMENT_DISABLE_IDENTITY`              | Sent when an identity is disabled                             |
| Disable Identity Failed       | `LIFECYCLE_MANAGEMENT_DISABLE_IDENTITY_FAILED`       | Sent when identity disabling fails                            |
| Create Guest Account          | `LIFECYCLE_MANAGEMENT_CREATE_GUEST_ACCOUNT`          | Sent when a guest account is created                          |
| Create Guest Account Failed   | `LIFECYCLE_MANAGEMENT_CREATE_GUEST_ACCOUNT_FAILED`   | Sent when guest account creation fails                        |
| Identity Deleted From Sources | `LIFECYCLE_MANAGEMENT_IDENTITY_DELETED_FROM_SOURCES` | Sent when an identity is deleted from its connected source(s) |

</details>

<details>

<summary>Relationship Management Events</summary>

| Event Type                 | API Usage Value                                   | Description                                      |
| -------------------------- | ------------------------------------------------- | ------------------------------------------------ |
| Add Relationship           | `LIFECYCLE_MANAGEMENT_ADD_RELATIONSHIP`           | Sent when a relationship is added                |
| Add Relationship Failed    | `LIFECYCLE_MANAGEMENT_ADD_RELATIONSHIP_FAILED`    | Sent when adding relationship fails              |
| Remove Relationship        | `LIFECYCLE_MANAGEMENT_REMOVE_RELATIONSHIP`        | Sent when a relationship is removed              |
| Remove Relationship Failed | `LIFECYCLE_MANAGEMENT_REMOVE_RELATIONSHIP_FAILED` | Sent when removing relationship fails            |
| Remove Direct Access       | `LIFECYCLE_MANAGEMENT_REMOVE_DIRECT_ACCESS`       | Sent when direct access to a resource is removed |

</details>

<details>

<summary>Email Management Events</summary>

| Event Type              | API Usage Value                                | Description                     |
| ----------------------- | ---------------------------------------------- | ------------------------------- |
| Create Email            | `LIFECYCLE_MANAGEMENT_CREATE_EMAIL`            | Sent when an email is created   |
| Create Email Failed     | `LIFECYCLE_MANAGEMENT_CREATE_EMAIL_FAILED`     | Sent when email creation fails  |
| Write Back Email        | `LIFECYCLE_MANAGEMENT_WRITE_BACK_EMAIL`        | Sent when email is synced back  |
| Write Back Email Failed | `LIFECYCLE_MANAGEMENT_WRITE_BACK_EMAIL_FAILED` | Sent when email sync back fails |

</details>

<details>

<summary>Password Management Events</summary>

| Event Type             | API Usage Value                               | Description                     |
| ---------------------- | --------------------------------------------- | ------------------------------- |
| Change Password        | `LIFECYCLE_MANAGEMENT_CHANGE_PASSWORD`        | Sent when a password is changed |
| Change Password Failed | `LIFECYCLE_MANAGEMENT_CHANGE_PASSWORD_FAILED` | Sent when password change fails |
| Reset Password         | `LIFECYCLE_MANAGEMENT_RESET_PASSWORD`         | Sent when a password is reset   |
| Reset Password Failed  | `LIFECYCLE_MANAGEMENT_RESET_PASSWORD_FAILED`  | Sent when password reset fails  |

</details>

<details>

<summary>Entitlement Management Events</summary>

| Event Type                | API Usage Value                                  | Description                          |
| ------------------------- | ------------------------------------------------ | ------------------------------------ |
| Create Entitlement        | `LIFECYCLE_MANAGEMENT_CREATE_ENTITLEMENT`        | Sent when an entitlement is created  |
| Create Entitlement Failed | `LIFECYCLE_MANAGEMENT_CREATE_ENTITLEMENT_FAILED` | Sent when entitlement creation fails |
| Rename Entitlement        | `LIFECYCLE_MANAGEMENT_RENAME_ENTITLEMENT`        | Sent when an entitlement is renamed  |
| Rename Entitlement Failed | `LIFECYCLE_MANAGEMENT_RENAME_ENTITLEMENT_FAILED` | Sent when entitlement renaming fails |
| Sync Entitlement          | `LIFECYCLE_MANAGEMENT_SYNC_ENTITLEMENT`          | Sent when an entitlement is synced   |
| Sync Entitlement Failed   | `LIFECYCLE_MANAGEMENT_SYNC_ENTITLEMENT_FAILED`   | Sent when entitlement sync fails     |

</details>

<details>

<summary>Actions and Workflows Events</summary>

| Event Type              | API Usage Value                                | Description                            |
| ----------------------- | ---------------------------------------------- | -------------------------------------- |
| Custom Action           | `LIFECYCLE_MANAGEMENT_CUSTOM_ACTION`           | Sent when a custom action is performed |
| Custom Action Failed    | `LIFECYCLE_MANAGEMENT_CUSTOM_ACTION_FAILED`    | Sent when custom action fails          |
| Action Succeed          | `LIFECYCLE_MANAGEMENT_ACTION_SUCCEED`          | Sent when an action succeeds           |
| Action Failed           | `LIFECYCLE_MANAGEMENT_ACTION_FAILED`           | Sent when an action fails              |
| Workflow Task Failed    | `LIFECYCLE_MANAGEMENT_WORKFLOW_TASK_FAILED`    | Sent when a workflow task fails        |
| Extraction Event Failed | `LIFECYCLE_MANAGEMENT_EXTRACTION_EVENT_FAILED` | Sent when extraction processing fails  |

</details>

<details>

<summary>Access Reviews Events</summary>

| Event Type                  | API Usage Value                                    | Description                        |
| --------------------------- | -------------------------------------------------- | ---------------------------------- |
| Create Access Review Queued | `LIFECYCLE_MANAGEMENT_CREATE_ACCESS_REVIEW_QUEUED` | Sent when access review is queued  |
| Create Access Review        | `LIFECYCLE_MANAGEMENT_CREATE_ACCESS_REVIEW`        | Sent when access review is created |

</details>

<details>

<summary>Safety Events</summary>

| Event Type                                | API Usage Value                                                 | Description                                                          |
| ----------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------- |
| Safety Limit Reached                      | `LIFECYCLE_MANAGEMENT_SAFETY_LIMIT_REACHED`                     | Sent when a hard safety limit is reached during processing           |
| Predictive Safety Limit Exceeded          | `LIFECYCLE_MANAGEMENT_PREDICTED_SAFETY_LIMIT_EXCEEDED`          | Sent when a predictive safety limit blocks changes before processing |
| Workflow Predictive Safety Limit Exceeded | `LIFECYCLE_MANAGEMENT_WORKFLOW_PREDICTED_SAFETY_LIMIT_EXCEEDED` | Sent when a workflow-level predictive safety limit blocks changes    |
| Invalid Identities Detected               | `LIFECYCLE_MANAGEMENT_INVALID_IDENTITIES_DETECTED`              | Sent when invalid identities are detected during policy execution    |

</details>

<details>

<summary>Access Request Events</summary>

| Event Type                       | API Usage Value                                         | Description                                    |
| -------------------------------- | ------------------------------------------------------- | ---------------------------------------------- |
| Access Request Created           | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_CREATED`           | Sent when an Access Request is created         |
| Access Request Action Run        | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_ACTION_RUN`        | Sent when Access Request actions start running |
| Access Request State Changed     | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_STATE_CHANGED`     | Sent when Access Request state changes         |
| Access Request Approver Assigned | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_APPROVER_ASSIGNED` | Sent when new approvers are assigned           |
| Access Request Succeed           | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_SUCCEED`           | Sent when Access Request succeeds              |
| Access Request Failed            | `LIFECYCLE_MANAGEMENT_ACCESS_REQUEST_FAILED`            | Sent when Access Request fails                 |

</details>

<details>

<summary>Non-Human Identity (NHI) Events</summary>

| Event Type | API Usage Value                   | Description                                   |
| ---------- | --------------------------------- | --------------------------------------------- |
| Rotate Key | `LIFECYCLE_MANAGEMENT_ROTATE_KEY` | Sent when a Non-Human Identity key is rotated |

</details>

### Default Template Content

Veza provides built-in email templates for all event types, organized by functional area below. These templates include standard placeholders and can be customized or replaced with your own templates.

<details>

<summary>Identity Management Templates</summary>

**CREATE\_IDENTITY**

* **Subject**: `New Hire Notification: {{ENTITY_TYPE}} account created`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Here is the information for your new-hire: {{ENTITY_NAME}} <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Login Name: {{LOGIN_NAME}} <br>
<br>
</body></html>
```

**CREATE\_GUEST\_ACCOUNT**

* **Subject**: `New {{ENTITY_TYPE}} Guest Account Created: {{ENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
New {{ENTITY_TYPE}} Guest Account Created <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Name: {{ENTITY_NAME}} <br>
Login Name: {{LOGIN_NAME}} <br>
Invite Sent: {{SENT_INVITE}} <br>
<br>
</body></html>
```

**SYNC\_IDENTITY**

* **Subject**: `Sync Identity Notification: {{ENTITY_TYPE}} account synced`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} attributes have been synced <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
<br>
</body></html>
```

**DELETE\_IDENTITY**

* **Subject**: `Identity Deleted Notification: {{ENTITY_TYPE}} has an account deleted`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has been deleted <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
<br>
</body></html>
```

**DISABLE\_IDENTITY**

* **Subject**: `Identity Disabled Notification: {{ENTITY_TYPE}} has an account disabled`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has been disabled <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
<br>
</body></html>
```

**IDENTITY\_DELETED\_FROM\_SOURCES**

* **Subject**: `Action Required - Identity Deleted: {{FULL_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
An identity has been deleted from the identity source(s). <strong>User accounts previously provisioned in connected systems may require review and cleanup.</strong><br>
<br>
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 12px; margin: 16px 0;">
<strong>Systems with Provisioned Accounts ({{SYNCED_ENTITY_COUNT}}):</strong><br>
{{SYNCED_ENTITY_LIST}}<br>
</div>
<br>
<strong>Required Actions:</strong><br>
<ol>
<li>Navigate to the <a href="{{IDENTITY_LINK}}" style="color: #007bff; font-weight: 600;">identity</a> in Veza</li>
<li>Review the provisioned accounts displayed for this identity</li>
<li>Run deprovisioning workflows to remove or disable dormant accounts</li>
</ol>
<br>
<strong>Identity Details:</strong><br>
Name: <a href="{{IDENTITY_LINK}}" style="color: #007bff;">{{FULL_NAME}}</a><br>
Email: {{EMAIL}}<br>
Employee ID: {{EMPLOYEE_ID}}<br>
Deleted At: {{DELETED_AT}}<br>
<br>
<hr style="margin-top: 20px; border: none; border-top: 1px solid #ddd;">
<small style="color: #666;">This is an automated notification from Veza Lifecycle Management. Please take appropriate action to ensure security and compliance.</small>
</body></html>
```

</details>

<details>

<summary>Relationship Management Templates</summary>

**ADD\_RELATIONSHIP**

* **Subject**: `New Relationship Added Notification: {{ENTITY_TYPE}} has an account with new relationship to a {{RELATIONSHIP_ENTITY_TYPE}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has a new relationship to {{RELATIONSHIP_ENTITY_NAME}} <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Relationship Type: {{RELATIONSHIP_ENTITY_TYPE}} <br>
<br>
</body></html>
```

**REMOVE\_RELATIONSHIP**

* **Subject**: `Relationship Removed Notification: {{ENTITY_TYPE}} has an account whose relationship was remove from a {{RELATIONSHIP_ENTITY_TYPE}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has a relationship removed from {{RELATIONSHIP_ENTITY_NAME}} <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Relationship Type: {{RELATIONSHIP_ENTITY_TYPE}} <br>
<br>
</body></html>
```

**REMOVE\_DIRECT\_ACCESS**

* **Subject**: `Direct Access Removed Notification: {{ENTITY_TYPE}} had direct access removed from {{RELATIONSHIP_ENTITY_TYPE}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} had direct access removed from {{RELATIONSHIP_ENTITY_NAME}} <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Resource Type: {{RELATIONSHIP_ENTITY_TYPE}} <br>
<br>
</body></html>
```

</details>

<details>

<summary>Email Management Templates</summary>

**CREATE\_EMAIL**

* **Subject**: `New Email Notification: {{ENTITY_TYPE}} has an account with new email`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has a new email address <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Email: {{EMAIL}} <br>
<br>
</body></html>
```

**WRITE\_BACK\_EMAIL**

* **Subject**: `New Write Back Email Notification: {{ENTITY_TYPE}} has had an email sync to it`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has the newly created email synced back to it <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Email: {{EMAIL}} <br>
<br>
</body></html>
```

</details>

<details>

<summary>Password Management Templates</summary>

**CHANGE\_PASSWORD**

* **Subject**: `Password Change Notification: {{ENTITY_TYPE}} has an account with a new password`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has a password <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Login Name: {{LOGIN_NAME}} <br>
New Password: {{LOGIN_PASSWORD}} <br>
<br>
</body></html>
```

**RESET\_PASSWORD**

* **Subject**: `Reset Password Notification: {{ENTITY_TYPE}} has had their password reset`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has had their password reset <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Login Name: {{LOGIN_NAME}} <br>
Temporary Password: {{LOGIN_PASSWORD}} <br>
<br>
</body></html>
```

</details>

<details>

<summary>Entitlement Management Templates</summary>

**CREATE\_ENTITLEMENT**

* **Subject**: `Create entitlement notification: an entry of {{ENTITY_TYPE}} is created`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
An entry of {{ENTITY_TYPE}} is created: {{ENTITY_NAME}} <br>
<br>
</body></html>
```

**RENAME\_ENTITLEMENT**

* **Subject**: `Rename entitlement notification: an entry of {{ENTITY_TYPE}} is renamed`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
An entry of {{ENTITY_TYPE}} is renamed with new name: {{ENTITY_NAME}} <br>
<br>
</body></html>
```

**SYNC\_ENTITLEMENT**

* **Subject**: `Sync entitlement notification: an entry of {{ENTITY_TYPE}} is renamed`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
An entry of {{ENTITY_TYPE}} has been re-synced with the target system: {{ENTITY_NAME}} <br>
<br>
</body></html>
```

</details>

<details>

<summary>Access Request Templates</summary>

**ACCESS\_REQUEST\_COMPLETE**

* **Subject**: `Access Request {{ACCESS_REQUEST_TYPE}} for {{ACCESS_REQUEST_ENTITY_NAME}} has {{SUCCEED_OR_FAILED}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ACCESS_REQUEST_ENTITY_NAME}} has been {{ACCESS_REQUEST_TYPE}} with: {{ACCESS_REQUEST_TARGET_NAME}}.<br>
<br>
User Type: {{ACCESS_REQUEST_ENTITY_TYPE}} <br>
Target Type: {{ACCESS_REQUEST_TARGET_TYPE}} <br>
<br>
</body></html>
```

**ACCESS\_REQUEST\_CREATED**

* **Subject**: `{{ACCESS_REQUEST_SOURCE_TYPE}} for {{ACCESS_REQUEST_ENTITY_NAME}} is {{ACCESS_REQUEST_STATE}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The request is currently in {{ACCESS_REQUEST_STATE}} state.
<br>
For details: {{ACCESS_REQUEST_URL}}
<br>
</body></html>
```

**ACCESS\_REQUEST\_FAILED**

* **Subject**: `{{ACCESS_REQUEST_SOURCE_TYPE}} for {{ACCESS_REQUEST_ENTITY_NAME}} is failed`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The request is failed, with an error message: {{EVENT_ERROR_MESSAGE}}
<br>
For details: {{ACCESS_REQUEST_URL}}
<br>
</body></html>
```

**ACCESS\_REQUEST\_STATE\_CHANGED**

* **Subject**: `{{ACCESS_REQUEST_SOURCE_TYPE}} for {{ACCESS_REQUEST_ENTITY_NAME}} is {{ACCESS_REQUEST_STATE}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The request is currently in {{ACCESS_REQUEST_STATE}} state.
<br>
For details: {{ACCESS_REQUEST_URL}}
<br>
</body></html>
```

**ACCESS\_REQUEST\_APPROVER\_ASSIGNED**

* **Subject**: `{{ACCESS_REQUEST_SOURCE_TYPE}} for {{ACCESS_REQUEST_ENTITY_NAME}} in {{ACCESS_REQUEST_STATE}} as new assigned approvers`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The request currently in {{ACCESS_REQUEST_STATE}} state has new been assigned new approvers.
<br>
For details: {{ACCESS_REQUEST_URL}}
<br>
</body></html>
```

</details>

<details>

<summary>Error and Failure Templates</summary>

**ACTION\_FAILED**

* **Subject**: `Action Failed: {{ACTION_NAME}} for identity {{IDENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Action has failed.<br>
<br>
Identity: {{IDENTITY_NAME}}<br>
Action Name: {{ACTION_NAME}}<br>
Action Type: {{ACTION_TYPE}}<br>
Workflow Name: {{WORKFLOW_NAME}}<br>
Error Message: {{EVENT_ERROR_MESSAGE}}<br>
<br>
</body></html>
```

**WORKFLOW\_TASK\_FAILED**

* **Subject**: `Workflow Failed: {{WORKFLOW_NAME}} for identity {{IDENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Workflow has failed.<br>
<br>
Identity: {{IDENTITY_NAME}}<br>
Workflow Name: {{WORKFLOW_NAME}}<br>
Error Message: {{EVENT_ERROR_MESSAGE}}<br>
<br>
</body></html>
```

**EXTRACTION\_EVENT\_FAILED**

* **Subject**: `Lifecycle Management extraction processing failed for {{DATASOURCE_ID}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Extraction processing has failed.<br>
<br>
Datasource: {{DATASOURCE_ID}}<br>
Error Message: {{EVENT_ERROR_MESSAGE}}<br>
<br>
</body></html>
```

</details>

<details>

<summary>Access Review Templates</summary>

**CREATE\_ACCESS\_REVIEW\_QUEUED**

* **Subject**: `Create Access Review Queued Notification: for identity {{IDENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
An access review has been queued for {{IDENTITY_NAME}} <br>
<br>
</body></html>
```

**CREATE\_ACCESS\_REVIEW**

* **Subject**: `Create Access Review Notification: for identity {{IDENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
An access review has been created for {{IDENTITY_NAME}} <br>
<br>
</body></html>
```

</details>

<details>

<summary>Safety and Custom Action Templates</summary>

**SAFETY\_LIMIT\_REACHED** (Hard Limit)

* **Subject**: `Safety Limit Reached Notification: Policy {{POLICY_NAME}} has stopped processing identity changes`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The hard safety limit for policy {{POLICY_NAME}} has been reached. No further identity changes were processed.<br>
</body></html>
```

**PREDICTED\_SAFETY\_LIMIT\_EXCEEDED** (Predictive Safety Limit)

* **Subject**: `Predictive Safety Limit Exceeded: Policy {{POLICY_NAME}} has blocked changes before processing`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
The predictive safety limit for policy {{POLICY_NAME}} has been exceeded. The predicted number of workflow runs exceeds the configured threshold. All changes have been blocked before processing. Review the blocked tasks and take action to proceed.<br>
</body></html>
```

**WORKFLOW\_PREDICTED\_SAFETY\_LIMIT\_EXCEEDED** (Workflow-Level Predictive Safety Limit)

* **Subject**: `Workflow Predictive Safety Limit Exceeded: A workflow in policy {{POLICY_NAME}} has blocked changes before processing`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
A workflow-level predictive safety limit in policy {{POLICY_NAME}} has been exceeded. The predicted number of workflow runs for the workflow exceeds its configured threshold. Review the blocked tasks and take action to proceed.<br>
</body></html>
```

**CUSTOM\_ACTION**

* **Subject**: `New Custom Action Notification: {{ENTITY_TYPE}} has performed a custom action`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
{{ENTITY_NAME}} has performed a custom action <br>
<br>
Account Type: {{ENTITY_TYPE}} <br>
Message: {{EVENT_ERROR_MESSAGE}} <br>
<br>
</body></html>
```

**INVALID\_IDENTITIES\_DETECTED**

* **Subject**: `Invalid Identities Detected: Policy {{POLICY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Invalid identities were detected during policy execution.<br>
<br>
Policy: {{POLICY_NAME}} <br>
Extraction Event: {{EXTRACTION_EVENT_ID}} <br>
<br>
Summary: {{EVENT_MESSAGE}} <br>
<br>
Please review the validation filters and check the individual invalid identity events in the policy history for detailed information.<br>
<br>
</body></html>
```

</details>

<details>

<summary>Non-Human Identity (NHI) Templates</summary>

**ROTATE\_KEY**

* **Subject**: `Key Rotation Notification: {{ENTITY_NAME}}`
* **Body**:

```html
<html><body>
Hello,<br>
<br>
Key {{ENTITY_NAME}} has been rotated.<br>
<br>
{{EVENT_MESSAGE}}<br>
<br>
</body></html>
```

</details>

### Image Attachments

From the Veza UI, you can add images directly through the "Add images" option. These will be automatically encoded and included in your template.

{% hint style="info" %}
**Image Requirements**: For API-based template management, small images under 64kb can be attached when configuring a template. The image must be base64-encoded and specified in the `attachments` field of the API request.
{% endhint %}

To use an attachment you have uploaded in a template, specify it by `attachment.name`, for example:

```html
<img src="cid:<name_of_attachment>"
```

To embed high-resolution images in your templates, you should serve the content from a public URL, and use HTML to link and style it.

### Placeholders

Use placeholders to include dynamic information in templates, such as entity names, action types, timestamps, and other event metadata. Placeholders are automatically replaced with actual values when notifications are sent.

{% hint style="warning" %}
**Placeholder Case Sensitivity**: Placeholders are **case-sensitive** and must match the exact casing shown in the documentation. For example, `{{ENTITY_TYPE}}` will work, but `{{entity_type}}` or `{{EntityType}}` will not be replaced unless those exact attribute names exist in your data.
{% endhint %}

#### How placeholders work

Veza notification templates support two types of placeholders:

**1. Static Placeholders (Predefined)**

These are uppercase constants documented in the tables below (e.g., `{{ENTITY_TYPE}}`, `{{ENTITY_NAME}}`). They are replaced first during template processing and work with all notification templates.

**Example:**

```html
Hello,
New account created for {{ENTITY_NAME}} with type {{ENTITY_TYPE}}.
```

**2. Dynamic Attribute Placeholders**

You can also reference **any attribute from the entities being processed** using two formats:

* **Untyped format**: `{{attribute_name}}` - References an attribute by name alone
* **Typed format**: `{{EntityType.attribute_name}}` - References an attribute from a specific entity type

The attribute name must **exactly match** the casing used by your integration. For example:

* If your integration provides an attribute named `email`, use `{{email}}`
* If it provides `Email`, use `{{Email}}`
* If it provides `employee_id`, use `{{employee_id}}`

**Examples:**

```html
<!-- Untyped - uses attribute from any entity -->
User email: {{email}}
Department: {{department}}

<!-- Typed - uses attribute from specific entity type -->
Okta email: {{OktaUser.email}}
AD username: {{ActiveDirectoryUser.sAMAccountName}}
```

{% hint style="info" %}
**When to Use Typed Format**: Use `{{EntityType.attribute}}` format when your workflow processes multiple entity types and you need to reference a specific entity's attributes. For example, if your workflow processes both `OktaUser` and `ActiveDirectoryUser`, use `{{OktaUser.email}}` to specifically reference the Okta user's email address.
{% endhint %}

#### Predefined placeholders

The following static placeholders are available in all notification templates:

<details>

<summary>Identity and Entity Information</summary>

| **Placeholder**      | **Description**                                              |
| -------------------- | ------------------------------------------------------------ |
| `{{ENTITY_TYPE}}`    | The type of entity (e.g., "ActiveDirectoryUser", "OktaUser") |
| `{{ENTITY_NAME}}`    | The name of the entity/identity                              |
| `{{LOGIN_NAME}}`     | The login/username for the account                           |
| `{{LOGIN_PASSWORD}}` | The password (for password-related notifications)            |
| `{{EMAIL}}`          | Email address associated with the identity                   |

</details>

<details>

<summary>Relationship Information</summary>

| **Placeholder**                | **Description**            |
| ------------------------------ | -------------------------- |
| `{{RELATIONSHIP_ENTITY_TYPE}}` | Type of the related entity |
| `{{RELATIONSHIP_ENTITY_NAME}}` | Name of the related entity |

</details>

<details>

<summary>Action and Job Information</summary>

| **Placeholder**         | **Description**                                                                           |
| ----------------------- | ----------------------------------------------------------------------------------------- |
| `{{ACTION_NAME}}`       | Name of the action being performed; serves as the stable unique identifier for the action |
| `{{ACTION_TYPE}}`       | Type of action                                                                            |
| `{{ACTION_JOB_ID}}`     | Unique identifier for the action job                                                      |
| `{{SUCCEED_OR_FAILED}}` | Status indicator ("succeeded" or "failed")                                                |
| `{{SENT_INVITE}}`       | Whether an invite was sent (for guest accounts)                                           |

</details>

<details>

<summary>Access Request Information</summary>

| **Placeholder**                  | **Description**                        |
| -------------------------------- | -------------------------------------- |
| `{{ACCESS_REQUEST_TYPE}}`        | Type of Access Request                 |
| `{{ACCESS_REQUEST_ENTITY_NAME}}` | Name of the entity requesting access   |
| `{{ACCESS_REQUEST_ENTITY_TYPE}}` | Type of the requesting entity          |
| `{{ACCESS_REQUEST_TARGET_TYPE}}` | Type of the target resource            |
| `{{ACCESS_REQUEST_TARGET_NAME}}` | Name of the target resource            |
| `{{ACCESS_REQUEST_URL}}`         | URL to view the Access Request details |
| `{{ACCESS_REQUEST_STATE}}`       | Current state of the Access Request    |
| `{{ACCESS_REQUEST_SOURCE_TYPE}}` | Source type of the Access Request      |

</details>

<details>

<summary>Event and Error Information</summary>

| **Placeholder**           | **Description**                         |
| ------------------------- | --------------------------------------- |
| `{{EVENT_TYPE}}`          | Type of lifecycle event                 |
| `{{JOB_ID}}`              | Job identifier                          |
| `{{EVENT_ERROR_MESSAGE}}` | Error message for failed events         |
| `{{EVENT_IDENTITY_ID}}`   | Identity ID associated with the event   |
| `{{EVENT_IDENTITY_NAME}}` | Identity name associated with the event |

</details>

<details>

<summary>Policy and Workflow Information</summary>

| **Placeholder**     | **Description**                                                               |
| ------------------- | ----------------------------------------------------------------------------- |
| `{{POLICY_NAME}}`   | Name of the lifecycle policy                                                  |
| `{{WORKFLOW_NAME}}` | Name of the workflow; serves as the stable unique identifier for the workflow |
| `{{DATASOURCE_ID}}` | Datasource identifier                                                         |

</details>

#### Troubleshooting placeholders

**Placeholder Not Being Replaced?**

If a placeholder appears in your notification email instead of being replaced with a value, check the following:

1. **Verify exact casing**: Placeholders are case-sensitive
   * ✅ Correct: `{{ENTITY_TYPE}}`
   * ❌ Wrong: `{{entity_type}}`, `{{EntityType}}`, `{{Entity_Type}}`
2. **Check placeholder format**: Ensure proper syntax with double curly braces
   * ✅ Correct: `{{ENTITY_NAME}}`
   * ❌ Wrong: `{ENTITY_NAME}`, `{{ENTITY_NAME}`, `ENTITY_NAME`
3. **Verify attribute exists**: For dynamic attributes, confirm the attribute is provided by your integration
   * Use the typed format to specify the entity type: `{{OktaUser.email}}`
   * Check your integration documentation for available attribute names and their casing
4. **Check event context**: Some placeholders are only available for specific events
   * For example, `{{LOGIN_PASSWORD}}` is only available for password-related events
   * `{{ACCESS_REQUEST_URL}}` is only available for Access Request events

**Best Practices:**

* **Start with predefined placeholders**: Use the documented static placeholders (uppercase) whenever possible
* **Test templates**: Send test notifications to verify placeholder replacement before deploying to production
* **Document custom attributes**: Keep a reference of the attribute names and casing used by your integrations
* **Use typed format for clarity**: When working with multiple entity types, use `{{EntityType.attribute}}` to avoid ambiguity

### Placeholder Resolution and Entity Scope

Whether a placeholder resolves to a value, and which record that value comes from, depends on two things: the form of the placeholder and the configuration surface the template is attached to. A placeholder that resolves correctly on one surface can fall through unresolved on another. This section describes how resolution works so you can author templates that reference the intended record.

#### What each placeholder form resolves against

Veza resolves three placeholder forms differently:

| Form                 | Example              | Resolves against                                                                                                      |
| -------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Built-in (uppercase) | `{{ACTION_NAME}}`    | Populated directly by the workflow runner. No entity lookup. See [Predefined placeholders](#predefined-placeholders). |
| Bare attribute       | `{{email}}`          | Source-of-identity (input) entities only. Never resolves a target-system attribute.                                   |
| Qualified attribute  | `{{OktaUser.email}}` | Output (target) entities first, then source-of-identity entities.                                                     |

For the qualified form, when an entity type appears in both the output entities and the source of identity, the output (target) value is used. This means `{{EntityType.attribute}}` is the only form that can reference an attribute written to the target system, and the bare form always reads from the source of identity.

{% hint style="warning" %}
A bare placeholder such as `{{email}}` reads only from the source-of-identity record that triggered the workflow. To reference an attribute on the account the workflow created or updated in a target system, you must use the qualified `{{EntityType.attribute}}` form with the exact registered entity type.
{% endhint %}

#### Which configuration surface provides which attributes

A notification template can be attached to three surfaces, and each receives a different set of attributes:

| Surface                                                                 | Source-of-identity attributes | Target (output entity) attributes                                               |
| ----------------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------- |
| Event-based notification (per policy event)                             | Available                     | Available when the event carries an action result that produced output entities |
| Action notification settings (`on_success` / `on_failure` on an action) | Available                     | Available from that action's output entities                                    |
| Send Notification action (standalone workflow node)                     | Available                     | Not available                                                                   |

{% hint style="warning" %}
The standalone **Send Notification** action runs with an empty job result, so it has no output entities. Templates on a Send Notification node can resolve source-of-identity attributes and built-in placeholders only. A qualified `{{EntityType.attribute}}` that points at a target system resolves to nothing on this surface. To send target-system attributes, attach the template to the action that produces them (for example, Sync Identities), using its `on_success` notification setting.
{% endhint %}

#### Which actions populate target attributes

Target (output entity) attributes are only available downstream when the action that ran produces output entities:

| Action                                           | Populates output entities                                                                                       |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| Sync Identities                                  | Yes. Target user attributes are available to subsequent actions and to its own notifications.                   |
| Send REST Request                                | Only when **Add Response to Output Entities** is enabled on the action.                                         |
| Send Notification                                | No. Runs with an empty result.                                                                                  |
| Pause, Deprovision, and similar terminal actions | Generally none of their own. Output entities from an earlier action in the same workflow can still be in scope. |

When in doubt, confirm the source of an attribute against the producing action rather than assuming it is available everywhere in the workflow.

#### Finding the canonical entity type for OAA integrations

The qualified form requires the exact entity type string that the integration registered, not a friendly label from the UI. For OAA integrations, that string has the form `OAA.<Provider Display Name>.<Entity Type>`, and it includes any spaces in the provider's display name.

For example, a Jira Cloud user's email attribute is referenced as:

```
{{OAA.Jira Cloud.User.email}}
```

The space inside `Jira Cloud` is required. Veza splits the entity type from the attribute on the final period, so spaces inside the provider name are preserved. If the provider display name contains a period, the qualified form cannot address it.

To find the canonical entity type for an integration, inspect an entity of that type in the Veza catalog or query the entity type through the API. Use the registered type string exactly as shown, including capitalization and spaces.

#### Template selection order

For a given notification, Veza selects the template to render in this order:

1. A custom template referenced by ID on the action or notification setting, if one is configured.
2. The template assigned to the matching event usage, if one exists.
3. The built-in default template for that event.

Selection is evaluated per configuration surface and per outcome (success or failure), so an action can use a custom template on success and fall back to the built-in default on failure.

#### Unresolved placeholders and unsupported syntax

Veza performs flat text substitution. It replaces each `{{key}}` token with its value and does not evaluate conditional or block logic. Handlebars-style block syntax such as `{{#if}}`, `{{/if}}`, `{{else}}`, partials (`{{>partial}}`), and comments (`{{!comment}}`) is not supported. These tokens never match an attribute, so they remain in the output and are reported as unresolved placeholders in the job's activity log.

If a notification arrives with literal `{{...}}` text in it, check the activity log for the unresolved-placeholder warning. It lists the exact tokens that did not resolve, which distinguishes a wrong entity type prefix from an attribute that was simply empty.

#### Additional placeholders

Beyond the [predefined placeholders](#predefined-placeholders) listed above, individual actions populate result-specific placeholders. Availability is context-dependent: each token is only set by the action or event that produces it, so a placeholder valid in one notification may be empty in another.

<details>

<summary>Action and result placeholders</summary>

| Placeholder                                                                                                                                            | Typical context                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------- |
| `{{EVENT_MESSAGE}}`                                                                                                                                    | Event notifications             |
| `{{EXTRACTION_EVENT_ID}}`                                                                                                                              | Extraction events               |
| `{{ACTION_URL}}`                                                                                                                                       | Action notifications            |
| `{{ANY_CHANGES}}`, `{{ANY_CREATED}}`, `{{SHOULD_STOP_NEXT_JOB}}`                                                                                       | Workflow change flags           |
| `{{IDENTITY_CREATED}}`, `{{IDENTITY_SYNCED}}`                                                                                                          | Create or sync identity results |
| `{{GUEST_ACCOUNT_CREATED}}`, `{{GUEST_ACCOUNT_INVITE_SENT}}`, `{{GUEST_ACCOUNT_SYNCED}}`                                                               | Guest account results           |
| `{{ATTRIBUTES_NOT_SYNCED}}`, `{{FAILED_ATTRIBUTE_DUE_TO_CONFLICT}}`                                                                                    | Sync identity results           |
| `{{CREATED_RELATIONSHIPS_COUNT}}`, `{{REMOVED_RELATIONSHIPS_COUNT}}`, `{{FAILED_CREATE_RELATIONSHIPS_COUNT}}`, `{{FAILED_REMOVE_RELATIONSHIPS_COUNT}}` | Relationship management results |
| `{{SOURCE_ENTITY_TYPE}}`, `{{SOURCE_ENTITY_ID}}`, `{{SOURCE_ENTITY_NAME}}`                                                                             | Source-of-identity reference    |
| `{{DEPROVISION_SUCCESSFUL}}`, `{{DEPROVISION_TYPE}}`, `{{LOGGED_OUT_USER}}`, `{{REMOVED_ALL_LICENSES}}`, `{{REMOVED_ALL_PERSONAL_DEVICES}}`            | Deprovision results             |
| `{{ENTITLEMENT_CREATED}}`, `{{ENTITLEMENT_RENAMED}}`, `{{ENTITLEMENT_SYNCED}}`, `{{MEMBERS_SYNCED_COUNT}}`                                             | Entitlement management results  |
| `{{RESULT_TYPE}}`, `{{PASSWORD_RESET_SUCCESSFUL}}`, `{{LOGIN}}`, `{{DELETE_SUCCESSFUL}}`                                                               | Action outcome results          |
| `{{ROTATED_KEY_COUNT}}`, `{{FAILED_KEY_COUNT}}`                                                                                                        | Key rotation results            |
| `{{FULL_NAME}}`, `{{EMPLOYEE_ID}}`, `{{DELETED_AT}}`, `{{IDENTITY_LINK}}`                                                                              | Identity reference              |
| `{{SYNCED_ENTITY_LIST}}`, `{{SYNCED_ENTITY_COUNT}}`                                                                                                    | Sync results                    |
| `{{EMAIL_ADDRESS}}`, `{{MESSAGE}}`                                                                                                                     | General                         |

</details>

### Webhook Configuration Overview

Webhook notifications are triggered upon execution of actions during the LCM Policy workflow process. Webhooks inform stakeholders or integrate with external systems of events that are processed within the workflow. Webhook notifications can be optionally configured as their own discrete action in a workflow or as an option when another action is executed.

For example, a webhook is sent to the company's learning management system to initiate online onboarding training once each new hire's Active Directory account is provisioned, following a successful Sync Identity operation.

#### Create a Webhook

To create and manage a webhook, perform the following:

1. Go to **Policies** and select a policy.
2. Click **Edit Policy**.
3. Click **Policy Settings**.
4. Scroll down to **Notifications** and click **Add Notification**.
5. Choose the **Webhook** notification type.
6. Choose an **event to trigger** notifications:
   * Create Identity
   * Sync Identity
   * Add Relationship
   * Remove Relationship
   * Create Email
   * Change Password
   * Delete Identity
   * Disable Identity
   * Manage Relationships
   * Write Back Email
   * Access Request Complete
   * Custom Action
   * Action Failed
   * Workflow Task Failed
   * Extraction Event Failed
   * Create Entitlement
   * Create Guest Account
   * Rename Entitlement
   * Create Access Review
   * Reset Password
   * Create Access Review Queued
   * Safety Limit Reached
   * Predictive Safety Limit Exceeded
   * Workflow Predictive Safety Limit Exceeded
   * Sync Entitlement
7. Choose the status to trigger notifications (when an event is **Successful**, or **On Failure**).
8. Select an **Existing Veza Action**.

   A Veza Action is an integration with functionality for sending data to external systems, enabling downstream processes around Veza alerts, and access to reviewer actions. Use a Veza Action to configure generic webhooks or enable email notifications.

   See Veza Actions [Webhooks](/4yItIzMvkpAvMVFAamTf/administration/administration/notifications/destinations/webhooks.md) on how to create and deploy a webhook.
9. To customize the Webhook setting, perform the following:

   * In the **Webhook URL** field, enter the endpoint configured to receive the webhook payload.
   * In the **Webhook Auth Header** field, enter the Auth Header if the webhook listener requires authentication.

   When configured, webhook requests include an Authorization header containing the credentials specified in the **Webhook Auth Header** field. This allows the receiving endpoint to authenticate the request using Bearer tokens, API keys, or other authentication schemes.
10. Click **Save**.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/policies-workflows/lifecycle-management-notification-templates.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
