# Placeholders Reference

This reference covers the placeholder tokens available for customizing Veza email templates. After reading this document, you will be able to:

* Use the correct placeholder syntax for each notification type
* Choose appropriate placeholders for Access Reviews, Lifecycle Management, and Access Intelligence templates
* Implement Handlebars loops and conditionals for dynamic content
* Troubleshoot common placeholder issues

## Overview

Placeholders are tokens wrapped in double curly braces (e.g., `{{PLACEHOLDER_NAME}}`) that Veza replaces with dynamic values when sending notifications. Each product area has its own set of placeholders based on the data available for that notification type.

**Document sections:**

* [Best practices](#best-practices) - Syntax rules and recommendations
* [Access Reviews placeholders](#access-reviews-placeholders) - Certification and digest notifications
* [Lifecycle Management placeholders](#lifecycle-management-placeholders) - Identity and provisioning events
* [Access Intelligence placeholders](#access-intelligence-placeholders) - Query alerts and risk notifications
* [Troubleshooting](#troubleshooting) - Common issues and solutions

## Best practices

This section covers placeholder syntax and conventions. For template testing procedures, see [Testing templates](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/administration/administration/notifications/customizing-templates#testing-templates) in the customization guide.

### Syntax and formatting

Placeholders use double curly braces with uppercase names:

```html
<!-- Correct -->
{{WORKFLOW_NAME}}
{{ENTITY_TYPE}}

<!-- These will not be replaced -->
{WORKFLOW_NAME}      <!-- single braces -->
{{workflow_name}}    <!-- wrong case -->
{{ WORKFLOW_NAME }}  <!-- spaces inside braces -->
```

Predefined placeholders (documented in this reference) use `UPPERCASE_WITH_UNDERSCORES`. Dynamic LCM attribute placeholders use the exact casing from your integration's attribute names.

### Handling empty values

When a placeholder has no value, Veza renders it as empty text rather than showing the placeholder token. Design your templates to handle missing data gracefully:

```html
<!-- Shows "Due date: " with nothing after if no due date -->
<p>Due date: {{WORKFLOW_CERT_DUE_ON_DATE}}</p>

<!-- Use Handlebars conditionals to hide the entire element -->
{{#if WORKFLOW_CERT_DUE_ON_DATE}}
<p>Due date: {{WORKFLOW_CERT_DUE_ON_DATE}}</p>
{{/if}}
```

These common placeholders may be empty:

* `{{WORKFLOW_CERT_DUE_ON_DATE}}` - reviews without due dates
* `{{DUE_DATE}}` in digest loops - certifications without due dates
* `{{EVENT_ERROR_MESSAGE}}` - successful events have no error
* `{{DIGEST_SUMMARY}}` - only populated if summaries are enabled

### Date and time formats

Access Reviews placeholders follow a naming convention for date formats:

| Suffix  | Format         | Example                         |
| ------- | -------------- | ------------------------------- |
| `_DATE` | Simple date    | "2024-01-15"                    |
| `_TIME` | Full timestamp | "Mon, Jan 15th 2024, 3:04:05PM" |

For example:

* `{{WORKFLOW_CERT_STARTED_ON_DATE}}` → "2024-01-15"
* `{{WORKFLOW_CERT_STARTED_ON_TIME}}` → "Mon, Jan 15th 2024, 9:00:00AM"

Choose based on your template's space constraints and detail requirements.

### LCM dynamic attributes

Lifecycle Management templates can reference entity attributes directly. Use the typed format when your workflow processes multiple entity types to avoid ambiguity:

```html
<!-- Untyped: works when only one entity type is involved -->
Department: {{department}}
Manager: {{manager}}

<!-- Typed: required when multiple entity types are in context -->
Okta department: {{OktaUser.department}}
AD department: {{ActiveDirectoryUser.department}}
```

Attribute names must match exactly as they appear in Veza, including casing. Check the entity's properties in **Access Intelligence** > **Overview** to confirm attribute names.

## Access Reviews placeholders

### Global placeholders

These placeholders are available in all Access Review notification templates:

| Placeholder                | Description                                 | Example Value                      |
| -------------------------- | ------------------------------------------- | ---------------------------------- |
| `{{WORKFLOW_NAME}}`        | Configuration name                          | "Q1 Access Review"                 |
| `{{WORKFLOW_TEXT}}`        | Default notification text (varies by event) | "A new certification was started"  |
| `{{WORKFLOW_URL}}`         | Link to the review in Veza                  | `https://tenant.veza.com/...`      |
| `{{WORKFLOW_TIME}}`        | Timestamp in GMT                            | "Mon, Jan 2nd 2024, 3:04:05PM"     |
| `{{WORKFLOW_OWNER}}`       | Configuration owner name                    | "John Smith"                       |
| `{{WORKFLOW_DESCRIPTION}}` | Configuration description                   | "Quarterly review of admin access" |

### Review (certification) placeholders

When a review exists for a configuration, these additional placeholders are available:

| Placeholder                               | Description                                    | Format                          |
| ----------------------------------------- | ---------------------------------------------- | ------------------------------- |
| `{{CERT_NAME}}`                           | Review name                                    | "Q1 Review - January 2024"      |
| `{{CERT_APPROVAL_LEVEL}}`                 | Current approval level (multi-level reviews)   | "1"                             |
| `{{CERT_APPROVAL_LEVEL_FINAL}}`           | Final approval level number                    | "2"                             |
| `{{CERT_APPROVAL_PHRASE_LEVEL}}`          | Approval level phrase (empty for single-level) | "at level 1 of 2"               |
| `{{WORKFLOW_CERT_DUE_ON_DATE}}`           | Due date                                       | "2024-01-15"                    |
| `{{WORKFLOW_CERT_STARTED_ON_DATE}}`       | Start date (simple)                            | "2024-01-01"                    |
| `{{WORKFLOW_CERT_STARTED_ON_TIME}}`       | Start date (full)                              | "Mon, Jan 1st 2024, 9:00:00AM"  |
| `{{WORKFLOW_CERT_COMPLETED_ON_DATE}}`     | Completion date                                | "2024-01-14"                    |
| `{{WORKFLOW_CERT_COMPLETED_ON_TIME}}`     | Completion timestamp                           | "Mon, Jan 14th 2024, 5:30:00PM" |
| `{{WORKFLOW_CERT_COMPLETED_BY}}`          | User who completed review                      | "Jane Doe"                      |
| `{{WORKFLOW_CERT_CREATED_BY}}`            | User who created review                        | "Admin User"                    |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_ON_DATE}}` | Last activity date                             | "2024-01-10"                    |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_ON_TIME}}` | Last activity timestamp                        | "Wed, Jan 10th 2024, 2:15:00PM" |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_BY}}`      | Last user to make changes                      | "John Smith"                    |
| `{{WORKFLOW_CERT_LAST_UPDATED_ON_DATE}}`  | Last update date                               | "2024-01-10"                    |
| `{{WORKFLOW_CERT_LAST_UPDATED_ON_TIME}}`  | Last update timestamp                          | "Wed, Jan 10th 2024, 2:15:00PM" |
| `{{WORKFLOW_CERT_LAST_UPDATED_BY}}`       | Last user to update                            | "John Smith"                    |
| `{{WORKFLOW_CERT_PHRASE}}`                | Review status phrase                           | "in progress"                   |

{% hint style="info" %}
**Date vs Time formats**: Placeholders ending in `_DATE` return simple format (e.g., "2024-01-02"). Placeholders ending in `_TIME` return full format (e.g., "Mon, Jan 2nd 2024, 3:04:05PM").
{% endhint %}

### Digest and review alert placeholders

Unique placeholders for `ACCESS_WORKFLOW_DIGEST_NOTIFICATION` and `ACCESS_WORKFLOW_REVIEW_ALERT`:

| Placeholder                                  | Description                                                                                   |
| -------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `{{DIGEST_NOTIFICATION_PERIOD}}`             | Time period covered (e.g., "January 1 - January 7, 2024" for digests, single date for alerts) |
| `{{CERTIFICATIONS_COUNT}}`                   | Number of reviews included                                                                    |
| `{{ACCESS_REVIEW_URL}}`                      | Link to Access Reviews overview                                                               |
| `{{SETTINGS_URL}}`                           | Link to notification settings (admin/operator only)                                           |
| `{{TABLE_PHRASE}}`                           | Header text: "My Reviews" (digest) or "New Reviews" (alert)                                   |
| `{{DIGEST_NOTIFICATION_TABLE}}`              | Pre-built HTML table of reviews                                                               |
| `{{DIGEST_NOTIFICATION_WITH_SUMMARY_TABLE}}` | Pre-built HTML table with summary column                                                      |

#### Certification data fields for Handlebars

When using `{{#each CERTIFICATIONS}}` to iterate over reviews:

| Field                | Type    | Description                     |
| -------------------- | ------- | ------------------------------- |
| `{{CERT_NAME}}`      | string  | Review name                     |
| `{{CERT_URL}}`       | string  | Link to review                  |
| `{{WORK_LEFT}}`      | number  | Items needing review            |
| `{{DUE_DATE}}`       | string  | Due date (empty if none)        |
| `{{OVERDUE}}`        | boolean | True if past due                |
| `{{NEW}}`            | boolean | True if recently created        |
| `{{DIGEST_SUMMARY}}` | string  | Workflow summary (max 64 chars) |

### Reviewer changed placeholders

For `ACCESS_WORKFLOW_REVIEWER_CHANGED`:

| Placeholder                       | Description             |
| --------------------------------- | ----------------------- |
| `{{WORKFLOW_CERT_OLD_REVIEWERS}}` | Previous reviewer names |
| `{{WORKFLOW_CERT_REVIEWERS}}`     | Current reviewer names  |

### Owner changed placeholders

For `ACCESS_WORKFLOW_OWNER_CHANGED`:

| Placeholder              | Description         |
| ------------------------ | ------------------- |
| `{{WORKFLOW_OLD_OWNER}}` | Previous owner name |

### Reminder placeholders

For `ACCESS_WORKFLOW_REMINDER_NO_ACTIVITY`:

| Placeholder                                          | Description                          |
| ---------------------------------------------------- | ------------------------------------ |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_DAYS}}`               | Days since last activity             |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_PHASE}}`              | Activity phrase (e.g., "for 3 days") |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_REVIEWER}}`           | Reviewer with no activity            |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_ROWS_TOTAL}}`         | Total rows assigned                  |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_ROWS_NEED_SIGN_OFF}}` | Rows needing sign-off                |
| `{{WORKFLOW_CERT_LAST_ACTIVITY_ROWS_SIGNED_OFF}}`    | Rows already signed off              |

For `ACCESS_WORKFLOW_REMINDER_DUE`:

| Placeholder                       | Description                                                 |
| --------------------------------- | ----------------------------------------------------------- |
| `{{WORKFLOW_CERT_DUE_IN_PHRASE}}` | Dynamic phrase: "is due on \[date]" or "was due on \[date]" |
| `{{WORKFLOW_CERT_DUE_ON_PHRASE}}` | Due date phrase                                             |
| `{{WORKFLOW_CERT_DUE_DAYS}}`      | Days until/since due date                                   |

### Row decision placeholders

For `ACCESS_WORKFLOW_ROW_ACCEPTED_AND_SIGNEDOFF` and `ACCESS_WORKFLOW_ROW_REJECTED_AND_SIGNEDOFF`:

| Placeholder                                                          | Description                                                        |
| -------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `{{REVIEW_ACCEPTED_REJECTED_ROWS_PHRASE}}`                           | Count phrase: "2 rows" or "1 row"                                  |
| `{{REVIEW_ACCEPTED_REJECTED_ROWS_DATA}}`                             | HTML list of affected rows                                         |
| `{{REVIEW_ACCEPTED_REJECTED_ROWS_DATA_WITH_NOTES}}`                  | HTML list with decision notes                                      |
| `{{REVIEW_ACCEPTED_REJECTED_ROWS_DATA_EXCLUDE_NODE_IDS}}`            | HTML list without node IDs                                         |
| `{{REVIEW_ACCEPTED_REJECTED_ROWS_DATA_WITH_NOTES_EXCLUDE_NODE_IDS}}` | HTML list with notes, without IDs                                  |
| `{{REVIEW_REJECTED_ROWS_ALL_ACCESS_PATHS}}`                          | Rejection only — attaches a CSV of rejected rows and related paths |

**Row data format examples:**

```html
<!-- REVIEW_ACCEPTED_REJECTED_ROWS_DATA -->
<p>[Result Id 1] From OktaUser "John Smith" (user123) to OktaGroup "Admins" (group456)</p>

<!-- REVIEW_ACCEPTED_REJECTED_ROWS_DATA_WITH_NOTES -->
<p>[Result Id 1] From OktaUser "John Smith" (user123) to OktaGroup "Admins" (group456) because of "Access no longer needed"</p>

<!-- REVIEW_ACCEPTED_REJECTED_ROWS_DATA_EXCLUDE_NODE_IDS -->
<p>[Result Id 1] From OktaUser "John Smith" to OktaGroup "Admins"</p>
```

### All access paths CSV attachment

`{{REVIEW_REJECTED_ROWS_ALL_ACCESS_PATHS}}` is available only for rejection notifications (`ACCESS_WORKFLOW_ROW_REJECTED_AND_SIGNEDOFF`).

{% hint style="warning" %}
**Email only**: This placeholder is only supported in email notification templates. Other notification actions are not affected (no CSV is generated when rejections are delivered via webhook).
{% endhint %}

When this placeholder is present in a template, Veza attaches a CSV file (`rejected_access_paths_<certId>.csv`) to the rejection email. The CSV groups the rejected row with any other access paths for the same user-to-resource pair **that exist within that certification**. Paths from other reviews or the full access graph are not included. Each group is separated by a blank row.

The placeholder renders inline as: "The attached csv lists the rejected row(s) and any additional access paths that might exist for the same user-to-resource combination(s)."

| Column                    | Description                                                                                                                                         |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Row Type`                | `REJECTED` for the reviewed row; `RELATED ACCESS PATH` for other paths to the same resource                                                         |
| `Principal Name`          | Identity name                                                                                                                                       |
| `Principal ID`            | Identity system identifier                                                                                                                          |
| `Principal Type`          | Entity type (e.g., `OktaUser`)                                                                                                                      |
| `Path Summary Node Names` | Intermediate nodes in the access path, joined with `->` (e.g., `Group Z -> Role Y`); empty if the workflow query has no Summary Entities configured |
| `Path Summary Node IDs`   | System identifiers for the intermediate nodes; empty if the workflow query has no Summary Entities configured                                       |
| `Resource Name`           | Target resource name                                                                                                                                |
| `Resource ID`             | Target resource system identifier                                                                                                                   |
| `Resource Type`           | Target entity type (e.g., `AwsIamRole`)                                                                                                             |
| `Rejection Notes`         | Decision notes — populated for `REJECTED` rows; empty for `RELATED ACCESS PATH` rows                                                                |
| `Rejected By`             | Reviewer email. Populated for `REJECTED` rows; empty for `RELATED ACCESS PATH` rows                                                                 |
| `Rejected At`             | Rejection timestamp — populated for `REJECTED` rows; empty for `RELATED ACCESS PATH` rows                                                           |

**Note:** When multiple rows are bulk-rejected in a single action, one email is sent with all rejected rows and related paths combined in one CSV. If a reviewer rejects the same user-to-resource pair in separate actions, each action sends its own email. Both include the full set of access paths for that pair.

### Phrase placeholders

Pre-built phrases used in default templates:

| Placeholder                                       | Output                                                                                                                                                                                        |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{ACCESS_WORKFLOW_STARTED_PHRASE}}`              | "Access Workflow --> Certification: A new certification was started on workflow {{WORKFLOW\_NAME}}"                                                                                           |
| `{{ACCESS_WORKFLOW_COMPLETED_PHRASE}}`            | "Access Certification: A certification on workflow {{WORKFLOW\_NAME}} has been completed"                                                                                                     |
| `{{ACCESS_WORKFLOW_REVIEWER_CHANGED_PHRASE}}`     | "Access Workflow: A new owner assigned to workflow {{WORKFLOW\_NAME}}"                                                                                                                        |
| `{{ACCESS_WORKFLOW_REMINDER_NO_ACTIVITY_PHRASE}}` | "Access Certification Reminder: Certification has had no activity from {{WORKFLOW\_CERT\_LAST\_ACTIVITY\_REVIEWER}} {{WORKFLOW\_CERT\_LAST\_ACTIVITY\_PHASE}} on workflow {{WORKFLOW\_NAME}}" |
| `{{ACCESS_WORKFLOW_REMINDER_DUE_PHRASE}}`         | "Access Certification Reminder: Certification {{WORKFLOW\_CERT\_DUE\_IN\_PHRASE}} on workflow {{WORKFLOW\_NAME}}"                                                                             |

***

## Lifecycle Management placeholders

LCM notifications use two distinct notification scopes, each with its own set of available placeholders:

* **Event notifications** are triggered by lifecycle events such as identity creation, action failure, or sync completion. These are configured under **Event Notifications** in a workflow's notification settings.
* **Action notifications** are triggered by the **Send Notification** action type within a workflow. These run as a step in the workflow pipeline.

{% hint style="warning" %}
**Placeholder scope matters**: Using a placeholder from the wrong scope causes it to appear as literal text (e.g., `{{JOB_ID}}`) in the email. Verify that each placeholder you use is listed under the correct scope below.
{% endhint %}

### Event notification placeholders

These placeholders are available when configuring notifications on lifecycle events (e.g., Action Failed, Identity Created, Sync Identities). They are populated from the lifecycle event context.

#### Identity and entity information

| Placeholder                    | Description                                           |
| ------------------------------ | ----------------------------------------------------- |
| `{{ENTITY_TYPE}}`              | Entity type (e.g., "ActiveDirectoryUser", "OktaUser") |
| `{{ENTITY_NAME}}`              | Entity/identity name                                  |
| `{{RELATIONSHIP_ENTITY_TYPE}}` | Related entity type                                   |
| `{{RELATIONSHIP_ENTITY_NAME}}` | Related entity name                                   |

#### Event and error information

| Placeholder               | Description                   |
| ------------------------- | ----------------------------- |
| `{{EVENT_TYPE}}`          | Lifecycle event type          |
| `{{JOB_ID}}`              | Job identifier                |
| `{{EVENT_ERROR_MESSAGE}}` | Error message (failed events) |
| `{{EVENT_MESSAGE}}`       | General event message text    |
| `{{EVENT_IDENTITY_ID}}`   | Identity ID                   |
| `{{EVENT_IDENTITY_NAME}}` | Identity name                 |
| `{{EXTRACTION_EVENT_ID}}` | Extraction event identifier   |

#### Policy and workflow information

| Placeholder         | Description           |
| ------------------- | --------------------- |
| `{{POLICY_NAME}}`   | Lifecycle policy name |
| `{{WORKFLOW_NAME}}` | Workflow name         |
| `{{DATASOURCE_ID}}` | Datasource identifier |

#### Event-type-specific placeholders

Some placeholders are only populated for specific event types:

| Placeholder               | Available for                     | Description                                   |
| ------------------------- | --------------------------------- | --------------------------------------------- |
| `{{LOGIN_NAME}}`          | Identity creation and sync events | Login username                                |
| `{{LOGIN_PASSWORD}}`      | Identity creation events          | Password (for password-related notifications) |
| `{{EMAIL}}`               | Email creation events             | Email address                                 |
| `{{SENT_INVITE}}`         | Guest account creation events     | Whether invite was sent                       |
| `{{EMAIL_ADDRESS}}`       | Email creation events             | Created email address                         |
| `{{FULL_NAME}}`           | Identity deleted events           | Full name of the deleted identity             |
| `{{EMPLOYEE_ID}}`         | Identity deleted events           | Employee identifier                           |
| `{{DELETED_AT}}`          | Identity deleted events           | Timestamp when the identity was deleted       |
| `{{IDENTITY_LINK}}`       | Identity deleted events           | Link to the identity record in Veza           |
| `{{SYNCED_ENTITY_LIST}}`  | Identity deleted events           | List of entities synced from this identity    |
| `{{SYNCED_ENTITY_COUNT}}` | Identity deleted events           | Count of entities synced from this identity   |

### Action notification placeholders

These placeholders are available when using the **Send Notification** action type in a workflow. They are populated from the action execution context.

| Placeholder             | Description                                         |
| ----------------------- | --------------------------------------------------- |
| `{{ACTION_NAME}}`       | Action name                                         |
| `{{ACTION_TYPE}}`       | Action type (e.g., SYNC\_IDENTITIES, CREATE\_EMAIL) |
| `{{ACTION_JOB_ID}}`     | Job identifier for the action                       |
| `{{ACTION_URL}}`        | URL to action details in Veza                       |
| `{{SUCCEED_OR_FAILED}}` | Status: "succeeded" or "failed"                     |

### Shared placeholders

The following placeholders are available in both event and action notifications when the corresponding action result data exists.

#### Action result placeholders

These placeholders are populated based on the specific action type:

**SYNC\_IDENTITIES actions:**

| Placeholder                            | Description                                   |
| -------------------------------------- | --------------------------------------------- |
| `{{IDENTITY_CREATED}}`                 | Whether identity was created                  |
| `{{IDENTITY_SYNCED}}`                  | Whether identity was synced                   |
| `{{GUEST_ACCOUNT_CREATED}}`            | Guest account created flag                    |
| `{{GUEST_ACCOUNT_INVITE_SENT}}`        | Invite sent flag                              |
| `{{GUEST_ACCOUNT_SYNCED}}`             | Whether guest account was synced              |
| `{{ATTRIBUTES_NOT_SYNCED}}`            | Comma-separated list of attributes not synced |
| `{{FAILED_ATTRIBUTE_DUE_TO_CONFLICT}}` | Attribute skipped due to a conflict           |

**MANAGE\_RELATIONSHIPS actions:**

| Placeholder                             | Description                            |
| --------------------------------------- | -------------------------------------- |
| `{{CREATED_RELATIONSHIPS_COUNT}}`       | Count of created relationships         |
| `{{REMOVED_RELATIONSHIPS_COUNT}}`       | Count of removed relationships         |
| `{{FAILED_CREATE_RELATIONSHIPS_COUNT}}` | Count of failed relationship creations |
| `{{FAILED_REMOVE_RELATIONSHIPS_COUNT}}` | Count of failed relationship removals  |

**DEPROVISION\_IDENTITY actions:**

| Placeholder                        | Description                   |
| ---------------------------------- | ----------------------------- |
| `{{DEPROVISION_SUCCESSFUL}}`       | Overall success flag          |
| `{{DEPROVISION_TYPE}}`             | Type of deprovision action    |
| `{{LOGGED_OUT_USER}}`              | User logged out flag          |
| `{{REMOVED_ALL_LICENSES}}`         | Licenses removed flag         |
| `{{REMOVED_ALL_PERSONAL_DEVICES}}` | Personal devices removed flag |

**RESET\_PASSWORD actions:**

| Placeholder                     | Description  |
| ------------------------------- | ------------ |
| `{{PASSWORD_RESET_SUCCESSFUL}}` | Success flag |
| `{{LOGIN}}`                     | Login name   |

**CUSTOM\_ACTION actions:**

| Placeholder   | Description                |
| ------------- | -------------------------- |
| `{{MESSAGE}}` | Custom action message text |

**CREATE\_ENTITLEMENT actions:**

| Placeholder                | Description                     |
| -------------------------- | ------------------------------- |
| `{{ENTITLEMENT_CREATED}}`  | Whether entitlement was created |
| `{{ENTITLEMENT_RENAMED}}`  | Whether entitlement was renamed |
| `{{ENTITLEMENT_SYNCED}}`   | Whether entitlement was synced  |
| `{{MEMBERS_SYNCED_COUNT}}` | Count of members synced         |

**ROTATE\_KEY actions:**

| Placeholder             | Description                         |
| ----------------------- | ----------------------------------- |
| `{{ROTATED_KEY_COUNT}}` | Count of successfully rotated keys  |
| `{{FAILED_KEY_COUNT}}`  | Count of keys that failed to rotate |

**DELETE\_IDENTITY actions:**

| Placeholder             | Description                         |
| ----------------------- | ----------------------------------- |
| `{{DELETE_SUCCESSFUL}}` | Whether identity deletion succeeded |

**CREATE\_ACCESS\_REVIEW actions:**

| Placeholder       | Description               |
| ----------------- | ------------------------- |
| `{{RESULT_TYPE}}` | Access review result type |

#### Source and relationship result placeholders

| Placeholder              | Description              |
| ------------------------ | ------------------------ |
| `{{SOURCE_ENTITY_TYPE}}` | Source entity type       |
| `{{SOURCE_ENTITY_ID}}`   | Source entity identifier |
| `{{SOURCE_ENTITY_NAME}}` | Source entity name       |

### Access Request notification placeholders

These placeholders are available for Access Request notifications within Lifecycle Management:

| Placeholder                      | Description             |
| -------------------------------- | ----------------------- |
| `{{ACCESS_REQUEST_TYPE}}`        | Request type            |
| `{{ACCESS_REQUEST_ENTITY_NAME}}` | Requesting entity name  |
| `{{ACCESS_REQUEST_ENTITY_TYPE}}` | Requesting entity type  |
| `{{ACCESS_REQUEST_TARGET_TYPE}}` | Target resource type    |
| `{{ACCESS_REQUEST_TARGET_NAME}}` | Target resource name    |
| `{{ACCESS_REQUEST_URL}}`         | Link to request details |
| `{{ACCESS_REQUEST_STATE}}`       | Current request state   |
| `{{ACCESS_REQUEST_SOURCE_TYPE}}` | Request source type     |

### Dynamic attribute placeholders

You can reference any attribute from entities being processed:

**Untyped format**: `{{attribute_name}}` - References attribute by name

**Typed format**: `{{EntityType.attribute_name}}` - References attribute from specific entity type

```html
<!-- Untyped -->
User email: {{email}}
Department: {{department}}

<!-- Typed (when processing multiple entity types) -->
Okta email: {{OktaUser.email}}
AD username: {{ActiveDirectoryUser.sAMAccountName}}
```

{% hint style="warning" %}
**Case sensitivity**: Placeholders are case-sensitive. `{{ENTITY_TYPE}}` works, but `{{entity_type}}` does not. Attribute names must match the exact casing from your integration.
{% endhint %}

***

## Access Intelligence placeholders

### Query alert placeholders (ASSESSMENT\_RULE\_QUERY\_ALERT)

| Placeholder                 | Description                                                    |
| --------------------------- | -------------------------------------------------------------- |
| `{{ALERT_TITLE}}`           | Alert/rule name                                                |
| `{{SEVERITY}}`              | Severity level (e.g., "High", "Medium", "Low")                 |
| `{{ALERT_TIME}}`            | Timestamp when alert was triggered                             |
| `{{QUERY_NAME}}`            | Name of the assessment query                                   |
| `{{QUERY_SOURCE}}`          | Source entity type (human-readable)                            |
| `{{QUERY_DESTINATION}}`     | Destination entity type (human-readable)                       |
| `{{CURRENT_VALUE}}`         | Current result count                                           |
| `{{PREVIOUS_VALUE}}`        | Previous result count (for comparison)                         |
| `{{THRESHOLD}}`             | Alert threshold value                                          |
| `{{CHANGE_AMOUNT}}`         | Absolute change in count                                       |
| `{{Change_Percent}}`        | Percentage change in count                                     |
| `{{CONDITION_DESCRIPTION}}` | Human-readable condition (e.g., "exceeded the threshold of 5") |
| `{{LINK_TO_ALERT_DETAILS}}` | URL to alert details in Veza                                   |
| `{{LINK_TO_QUERY}}`         | URL to assessment query                                        |
| `{{CURRENT_YEAR}}`          | Current year (for footer/copyright)                            |

### Property alert placeholders (ASSESSMENT\_RULE\_QUERY\_PROPERTIES)

Property alerts include all query alert placeholders above, plus:

| Placeholder         | Description                       |
| ------------------- | --------------------------------- |
| `{{PROPERTY_NAME}}` | Name of the tracked node property |

### Risk notification placeholders (ASSESSMENT\_RISK)

| Placeholder      | Description                |
| ---------------- | -------------------------- |
| `{{RISK_LEN}}`   | Number of risks identified |
| `{{QUERY_NAME}}` | Risk query name            |

#### Handlebars context for risk lists

Use `{{#each RISK_ROWS}}` to iterate through identified risks. Each item contains the entity type and name.

***

## Troubleshooting

### Placeholder not being replaced

If a placeholder appears literally in your email instead of being replaced:

1. **Verify casing**: Placeholders are case-sensitive
   * Correct: `{{ENTITY_TYPE}}`
   * Wrong: `{{entity_type}}`, `{{EntityType}}`
2. **Check syntax**: Ensure proper double curly braces
   * Correct: `{{ENTITY_NAME}}`
   * Wrong: `{ENTITY_NAME}`, `{{ENTITY_NAME}`
3. **Verify availability**: Some placeholders are only available for specific notification types
   * `{{LOGIN_PASSWORD}}` only works for password events
   * `{{ACCESS_REQUEST_URL}}` only works for Access Request events
4. **Check attribute existence**: For dynamic LCM attributes, verify the attribute name and casing from your integration

### All LCM placeholders appearing as literal text

If **all** or **most** placeholders in an LCM notification template render as literal text (e.g., the email body shows `{{JOB_ID}}` and `{{EVENT_IDENTITY_NAME}}` instead of actual values), you are most likely using placeholders from the wrong notification scope:

* **Event notification placeholders** (such as `{{JOB_ID}}`, `{{EVENT_IDENTITY_NAME}}`, `{{EVENT_ERROR_MESSAGE}}`, `{{WORKFLOW_NAME}}`) are **only available in event notifications**. They are not replaced when used in a Send Notification action template.
* **Action notification placeholders** (such as `{{ACTION_NAME}}`, `{{ACTION_TYPE}}`, `{{SUCCEED_OR_FAILED}}`, `{{ACTION_JOB_ID}}`) are **only available in the Send Notification action**.

To fix this, check whether your template is configured for an event notification or a Send Notification action, and use only the placeholders listed under the corresponding scope in the [Lifecycle Management placeholders](#lifecycle-management-placeholders) section above.

{% hint style="info" %}
**`{{WORKFLOW_URL}}` is not available in Lifecycle Management.** This placeholder is specific to [Access Reviews](#access-reviews-placeholders). If you need to link to a workflow from an LCM notification, use `{{ACTION_URL}}` in action notifications instead.
{% endhint %}
