> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/ticketing/ticket-rules/placeholders.md).

# Template placeholders

Every ${…} placeholder a ticket rule template can use, the triggers that fill it, and how values are rendered into the ticket's summary, description, comment and additional fields.

## What this is, and when you need it

A ticket rule's **Summary**, **Description**, **Comment** and additional field values are templates. A `${…}` placeholder in them is replaced by a value from the event — the request, the users involved, the managed system, the non-human identity — when the rule fires. This page lists every placeholder, which triggers can fill it, and the rendering rules. Look a placeholder up here when a ticket shows an empty gap where you expected a name.

How to write the templates themselves is on [Write a ticket rule](/administration-guide/ticketing/ticket-rules.md#rule-content).

## How placeholders are rendered

| Rule                      | Detail                                                                                                                                                                                                                                    |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Syntax                    | `${key}`, where the key is letters, digits, `_` and `.` — `${targetUser.displayName}`                                                                                                                                                     |
| No value                  | A placeholder whose value is missing renders as an empty string. Rendering never fails a ticket                                                                                                                                           |
| Dates                     | ISO-8601 in UTC: `2026-10-22T09:15:00Z`                                                                                                                                                                                                   |
| `${changedAttributes}`    | The changed names, sorted, joined with `,`                                                                                                                                                                                                |
| `${request.items}`        | One `- <name>` line per requested item: roles first, then groups, then resources, each sorted by name. Items whose name cannot be resolved are left out. Because each line starts with `-` , the list becomes a bullet list in the ticket |
| `${event.context.<name>}` | Reads a raw value the event carries, by name. Always allowed, never checked; renders empty when the event has no such value                                                                                                               |
| Additional fields         | Rendered like the summary. A field that renders empty is not sent                                                                                                                                                                         |

A template is checked when you save the rule: a placeholder the catalogue does not know, or one that not every selected trigger can fill, blocks **Save rule**.

### Insert placeholder <a href="#ph-insert" id="ph-insert"></a>

Every template field of the rule editor has **Insert placeholder**. It opens a searchable list grouped like the tables below (search by label or by key) and inserts `${key}` at the cursor.

The list offers only the placeholders **every** selected trigger can fill: a rule on **Request submitted** and **Request step decided** does not offer `${decision}`, because the submission has no decision. Under each template the placeholders show as chips:

| Chip                          | Meaning                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------- |
| Blue                          | Known and available for all selected triggers                                                 |
| Amber, dashed, struck through | *Not available for the selected triggers* — remove it or drop the trigger that cannot fill it |
| Red, wavy underline           | *Unknown placeholder* — a typo or a key that does not exist                                   |

Amber and red chips block **Save rule**. If the list of available placeholders cannot be loaded, the editor offers the whole catalogue and flags nothing; the server still checks on save.

In the tables, **Filled for** names the triggers that can fill the placeholder. *Request* means the eight request lifecycle triggers and **Access revoked**.

## Request <a href="#ph-group-request" id="ph-group-request"></a>

| Placeholder                | Label in the picker   | Filled for |
| -------------------------- | --------------------- | ---------- |
| `${request.id}`            | Request id            | Request    |
| `${request.type}`          | Request type          | Request    |
| `${request.name}`          | Request name          | Request    |
| `${request.status}`        | Request status        | Request    |
| `${request.description}`   | Request description   | Request    |
| `${request.justification}` | Request justification | Request    |
| `${request.createdAt}`     | Request creation time | Request    |
| `${request.items}`         | Requested item ids    | Request    |

The picker labels `${request.items}` *Requested item ids*, but the ticket receives the items' names as a bullet list, not their ids.

## Requester <a href="#ph-group-requester" id="ph-group-requester"></a>

The person who raised the request.

| Placeholder                | Label in the picker    | Filled for |
| -------------------------- | ---------------------- | ---------- |
| `${requester.displayName}` | Requester display name | Request    |
| `${requester.firstName}`   | Requester first name   | Request    |
| `${requester.lastName}`    | Requester last name    | Request    |
| `${requester.email}`       | Requester email        | Request    |
| `${requester.login}`       | Requester login        | Request    |
| `${requester.employeeId}`  | Requester employee id  | Request    |

## Target user <a href="#ph-group-target-user" id="ph-group-target-user"></a>

The user the event is about: the beneficiary of a request, the created, edited or terminated user, the user being provisioned.

| Placeholder                  | Label in the picker      | Filled for                              |
| ---------------------------- | ------------------------ | --------------------------------------- |
| `${targetUser.displayName}`  | Target user display name | Request, user and provisioning triggers |
| `${targetUser.firstName}`    | Target user first name   | same                                    |
| `${targetUser.lastName}`     | Target user last name    | same                                    |
| `${targetUser.email}`        | Target user email        | same                                    |
| `${targetUser.login}`        | Target user login        | same                                    |
| `${targetUser.employeeId}`   | Target user employee id  | same                                    |
| `${targetUser.title}`        | Target user title        | same                                    |
| `${targetUser.department}`   | Target user department   | same                                    |
| `${targetUser.organization}` | Target user organization | same                                    |

For a group provisioning event there is no target user, so these render empty.

## Manager <a href="#ph-group-manager" id="ph-group-manager"></a>

The target user's primary supervisor, or the first supervisor when none is marked primary.

| Placeholder              | Label in the picker  | Filled for                              |
| ------------------------ | -------------------- | --------------------------------------- |
| `${manager.displayName}` | Manager display name | Request, user and provisioning triggers |
| `${manager.email}`       | Manager email        | same                                    |
| `${manager.login}`       | Manager login        | same                                    |

## Workflow step <a href="#ph-group-step" id="ph-group-step"></a>

The approval step the event is about.

| Placeholder                    | Label in the picker   | Filled for                                                     |
| ------------------------------ | --------------------- | -------------------------------------------------------------- |
| `${step.approver.displayName}` | Approver display name | Request step decided, delegated, escalated, cancelled, expired |
| `${step.approver.email}`       | Approver email        | same                                                           |
| `${step.approver.login}`       | Approver login        | same                                                           |
| `${step.name}`                 | Step name             | same                                                           |
| `${step.comment}`              | Step comment          | same                                                           |
| `${decision}`                  | Decision              | Request step decided only: `approved` or `rejected`            |

## Managed system <a href="#ph-group-managed-system" id="ph-group-managed-system"></a>

The managed system of a provisioning event — not the ticketing system, which is `${ticketSystem.name}`.

| Placeholder             | Label in the picker    | Filled for                                                    |
| ----------------------- | ---------------------- | ------------------------------------------------------------- |
| `${managedSystem.id}`   | Managed system id      | Provisioning failed, Provisioning succeeded                   |
| `${managedSystem.name}` | Managed system name    | same                                                          |
| `${operation}`          | Provisioning operation | same: `SAVE`, `DELETE`, `RESET_PASSWORD`, `SUSPEND`, `RESUME` |
| `${error.message}`      | Error message          | Provisioning failed only                                      |

## Ticket <a href="#ph-group-ticket" id="ph-group-ticket"></a>

| Placeholder             | Label in the picker   | Filled for                       |
| ----------------------- | --------------------- | -------------------------------- |
| `${ticketSystem.name}`  | Ticketing system name | Every trigger                    |
| `${rule.name}`          | Rule name             | Every trigger                    |
| `${ticket.externalKey}` | Existing ticket key   | Every trigger; empty on a create |
| `${ticket.subjectKey}`  | Subject key           | Every trigger                    |

`${ticket.externalKey}` is useful in a comment that refers to the ticket, never in a create's summary.

## Event <a href="#ph-group-event" id="ph-group-event"></a>

| Placeholder            | Label in the picker | Filled for                                                                                                                                             |
| ---------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `${event.id}`          | Event id            | Every trigger                                                                                                                                          |
| `${event.trigger}`     | Trigger             | Every trigger: the constant, such as `REQUEST_SUBMITTED`                                                                                               |
| `${event.occurredAt}`  | Event time          | Every trigger                                                                                                                                          |
| `${actor.displayName}` | Initiated by        | Every trigger: the administrator who saved the user, the approver, the requester, the provisioning initiator. Empty for a system run such as an expiry |
| `${changedAttributes}` | Changed attributes  | User edited only                                                                                                                                       |

## Non-human identity <a href="#ph-group-nhi" id="ph-group-nhi"></a>

Filled from a snapshot of the identity taken when the event happened.

| Placeholder                                                                 | Label in the picker                               | Filled for                               |
| --------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------- |
| `${nhi.name}`, `${nhi.type}`, `${nhi.status}`                               | NHI name, type, status                            | NHI triggers                             |
| `${nhi.environment}`, `${nhi.riskClassification}`, `${nhi.expiryDate}`      | NHI environment, risk classification, expiry date | NHI triggers                             |
| `${nhi.owner.displayName}`, `${nhi.owner.email}`, `${nhi.owner.login}`      | NHI owner display name, email, login              | NHI triggers                             |
| `${nhi.backupOwner.displayName}`, `${nhi.backupOwner.email}`                | NHI backup owner display name, email              | NHI triggers                             |
| `${nhi.sponsor.displayName}`, `${nhi.sponsor.email}`                        | NHI sponsor display name, email                   | NHI triggers                             |
| `${nhi.previousOwner.displayName}`                                          | NHI previous owner display name                   | NHI owner changed only                   |
| `${nhi.fromStatus}`, `${nhi.toStatus}`                                      | NHI previous status, NHI new status               | NHI activated, suspended, decommissioned |
| `${credential.type}`, `${credential.expiryDate}`, `${credential.operation}` | Credential type, expiry date, operation           | NHI credential changed only              |

## Worked example

Rule 1 of the running example, **Access request opened**, has this summary and description:

{% code overflow="wrap" %}

```
Access request ${request.name} for ${targetUser.displayName}

Requested by ${requester.displayName}.
Justification: ${request.justification}

Items:
${request.items}
```

{% endcode %}

When Jordan Lee requests *Finance Reports* access for Sam Patel, `ACCESS-142` is created with the summary `Access request Finance Reports for Sam Patel` and this description, the item list rendered as bullets:

{% code overflow="wrap" %}

```
Requested by Jordan Lee.
Justification: Quarter-end reporting for the EMEA region

Items:
- Finance Reports Viewer
```

{% endcode %}

Rule 2 on the same ticket, with `${step.approver.displayName} decided ${decision} on ${step.name}: ${step.comment}`, adds the comment `Priya Nair decided approved on Manager approval: OK for Q4.` The exact request name and step name are the ones your workflow gives them.

## When it goes wrong <a href="#when-it-goes-wrong" id="when-it-goes-wrong"></a>

| Symptom                                                 | Likely cause                                                                                                        | Resolution                                                                         |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| **Save rule** is disabled and a chip is amber           | The placeholder is not available for one of the selected triggers                                                   | Remove it, or remove the trigger that cannot fill it                               |
| A chip is red                                           | Unknown placeholder, usually a typo or wrong case                                                                   | Pick it from **Insert placeholder**                                                |
| A value is empty in the ticket                          | The event carried no such value: no manager on the user, no justification on the request, a group instead of a user | Check the source record; use fields that are always set in the summary             |
| `${actor.displayName}` is empty                         | A system run (expiry, scheduled check, synchronization)                                                             | Expected                                                                           |
| `${request.items}` is empty or shorter than the request | Names of some items could not be resolved, or the request carries no items                                          | Check the requested roles, groups and resources still exist                        |
| `${event.context.something}` is empty                   | The event does not carry that value                                                                                 | Use a catalogue placeholder; `event.context` values are not documented per trigger |
| Dates show in UTC                                       | Dates always render in UTC                                                                                          | Add `UTC` to the text around the placeholder                                       |

## Related

* [Write a ticket rule](/administration-guide/ticketing/ticket-rules.md) — the content card and the live preview.
* [Triggers and conditions](/administration-guide/ticketing/ticket-rules/triggers-and-conditions.md) — what each trigger is about.
* [How fields reach Jira and ServiceNow](/administration-guide/ticketing/jira-and-servicenow.md) — how rendered text is formatted in each system.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/ticketing/ticket-rules/placeholders.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
