> 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/developers/api/workflows/automations.md).

# Automations API

Use these operations to manage Access Review Automations and associate them with individual workflows.

Automations apply changes (such as approve, sign-off, add a note, or apply visual indicators) to Certification rows based on historical certification data, or a filter on the current results. They can run by default or on an opt-in basis when a certification is created.

## Example Automations

```json
{
  "id": "e48dd2c8-3633-463b-a477-0177a942b5a6",
  "name": "Highlight inactive sources",
  "description": "Highlight rows where the source account is inactive",
  "priority": 0,
  "attachment_behavior": {
    "attach_to_new_workflows": true,
    "opt_in": true
  },
  "criteria": {
    "filter": "source.is_active eq false",
    "mutable_filter": ""
  },
  "action": {
    "display_style": "HIGHLIGHT",
    "display_text": "Source account is inactive",
    "highlight_color": "#FF6B35"
  }
}
```

```json
{
  "id": "f59ee3d9-4744-574c-b588-1288b0942c7c",
  "name": "Reject privileged account access",
  "description": "Suggest reject for admin or root accounts",
  "priority": 0,
  "attachment_behavior": {
    "attach_to_new_workflows": true,
    "opt_in": true
  },
  "criteria": {
    "filter": "(destination.name eq \"admin\") OR (source.name eq \"root\")",
    "mutable_filter": ""
  },
  "action": {
    "display_style": "SUGGEST_REJECT",
    "display_text": "Privileged account detected - review carefully"
  }
}
```

For more information about this feature see [Intelligent Automations](/4yItIzMvkpAvMVFAamTf/features/access-reviews/configuration/review-intelligence-rules.md).

You will need an API token with root team or administrator permissions to manage Automations.

## Key Concepts

When working with the Automations API, it is important to understand the relationship between three identifiers:

| ID Type              | Description                                                                     | Scope                                                  |
| -------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------ |
| **Automation ID**    | Unique identifier for a reusable Automation rule                                | Global (can be attached to multiple workflows)         |
| **Workflow ID**      | Unique identifier for an Access Review configuration                            | Defines the query, reviewers, and settings for reviews |
| **Certification ID** | Unique identifier for a specific Access Review instance created from a workflow | A single review cycle with results to act upon         |

At an API level,

* An **Automation** is a reusable rule that can be attached to one or more **Workflows**
* A **Workflow** (review configuration) defines how reviews are created and can have multiple **Certifications** over time
* A **Certification** is a single instance of a review where Automations run against the results

## Error handling and conflicts

The following rules apply when an Automation run encounters an issue:

* If Automation processing fails for any result, the Automation run stops and no further Automations are applied.
* When Automations fail, the Certification is still considered complete and non-errored. The Automation run will have an error status and message.

Results are considered the same when the entities and relationships are exactly equal (including data source IDs). If a conflict occurs with Automations trying to change the same mutable field:

* Each change must update the field to the same value. The action log entry will contain notes (if supplied) for each action.
* Automations changing a field to differing values are unresolvable conflicts and skipped, but will not interrupt the Automation run.

## Automation Object Schema

An Automation consists of `attachment_behavior` rules, filter `criteria`, and an `action` to apply:

```json
{
  "id": "string",
  "name": "string",
  "description": "string",
  "priority": 0,
  "attachment_behavior": {
    "attach_to_new_workflows": boolean,
    "opt_in": boolean
  },
  "criteria": {
    "filter": "string",
    "mutable_filter": "string"
  },
  "action": {
    // For modification actions:
    "decision": "string",
    "signed_off_state": "string",
    "notes": "string",
    "reviewer_assignment": null,

    // OR for display actions:
    "display_style": "string",
    "display_text": "string",
    "highlight_color": "string"
  }
}
```

Each Automation object has the fields:

* `id` (String): Unique identifier for the Automation.
* `name` (String): Name of the Automation.
* `description` (String): A brief description of the Automation.
* `priority` (Integer): Priority value of the Automation (not currently supported).

#### `attachment_behavior` (Object)

Defines if the Automation is available for all workflows, and whether it is optional:

* `attach_to_new_workflows` (Boolean): Indicates whether to automatically attach to new and existing workflows.
* `opt_in` (Boolean): If `true` Operators can pick the automation when creating a Workflow. If `false` the automation is enabled by default.

#### `criteria` (Object)

Specifies filters for conditionally updating results:

* `filter` (String): A SCIM filter specifying a source or destination attribute with support for complex expressions using AND, OR, and parentheses for grouping. *Examples:*
  * Simple filter: `source.is_active eq false`
  * Complex filter: `(source.name sw "A" OR source.name sw "B") AND destination.is_active eq true`
* `mutable_filter` (String): A filter on a previous result mutable field using the syntax `previous.attribute`. *Example: "previous.decision eq "RESULT\_DECISION\_ACCEPTED""*

Similarly to Smart Actions, Automations can update results based on a source or destination attribute (such as activity status). Filters use the syntax `source.attribute` or `destination.attribute`.

## AWF Automation Filter Grammar

The `filter` field in an Automation's `criteria` accepts a SCIM-style expression. Each filter field referenced in the expression is either a bare `field` or a two-part `endpoint.field`. Filter fields with three or more dot-separated segments (for example, `source.tags.value`, `reviewers.id`, or `decision.by`) are invalid and are rejected at parse time.

A filter that fails to parse prevents the Automation from running. When multiple Automations are attached to a Certification, a single unparseable filter on any one of them blocks every attached Automation from running on that Certification.

### Two-part form: `endpoint.field`

The `endpoint` must be one of the following:

| Endpoint        | Valid fields                                                                                                                          |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `source`        | `id`, `name`, `type`, `alternate_name`, `veza_unique_name`, `tags`, or any property key stored on the source node                     |
| `destination`   | `id`, `name`, `type`, `alternate_name`, `veza_unique_name`, `tags`, or any property key stored on the destination node                |
| `waypoint`      | `id`, `name`, `type`, `alternate_name`, `veza_unique_name`, or any property key stored on the waypoint node. `tags` is not supported. |
| `path_summary`  | `id`, `name`, `type`                                                                                                                  |
| Join-spec alias | Any property key stored on the joined node (same fields as `source`). The alias must be declared on the workflow's query.             |

Notes on two-part form:

* `tags` matches on the tag **key** only, never the value. For example, `source.tags eq "owner"` matches any source node carrying a tag whose key is `owner`, regardless of that tag's value.
* Use the exact property key as stored on the node. Built-in properties use their own name (for example, `source.is_active`). Customer-ingested custom properties carry the `customprop_` prefix that is applied during ingest (for example, `source.customprop_attribute_code`).
* Join-spec aliases are valid only when the workflow's query declares a joined node with that alias. See [Filtering by Joined Node Attributes](#filtering-by-joined-node-attributes) for finding and using aliases.

### One-part form: `field`

Bare fields refer to attributes of the Certification result row itself, not to the source, destination, waypoint, or path-summary nodes. The `field` must be exactly one of the following:

| Category                         | Fields                                                                                                                         |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Decision and sign-off state      | `status`, `decision`, `signed_off_state`, `is_signed_off`, `no_decision_or_decision_by`                                        |
| Decision actor and timestamp     | `decision_by`, `decision_by_id`, `decision_by_name`, `decision_by_email`, `decision_at`                                        |
| Marked-fixed actor and time      | `marked_fixed_by_id`, `marked_fixed_by_name`, `marked_fixed_by_email`, `marked_fixed_at`                                       |
| Sign-off actor and timestamp     | `signed_off_by_id`, `signed_off_by_name`, `signed_off_by_email`, `signed_off_at`                                               |
| Reviewers and assignment         | `reviewers`, `is_assigned_to_current_user`                                                                                     |
| Risk and access metadata         | `risk_level`, `access_path_risk_score`, `access_stats_last_used`, `is_outlier`, `abstract_permissions`, `concrete_permissions` |
| AI suggestions                   | `ai_suggestion_type`, `ai_suggestion_reason_codes`, `ai_suggestion_cohort_id`, `ai_suggestion_cohort_index`                    |
| Notes, automation, notifications | `notes`, `updated_at`, `notification_status`, `automation_run_ids`                                                             |

These fields are **bare-only**. Dotted forms such as `reviewers.id`, `decision.by`, or `signed_off_state.id` are not supported and are rejected at parse time.

### Invalid filter examples

The following filter expressions do not conform to the grammar and are rejected when an Automation is created or updated:

| Filter                               | Reason                                                                                                                                                                 |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reviewers.id eq "12345"`            | `reviewers` is a bare field. Dotted form is not supported.                                                                                                             |
| `decision.by eq "alice@example.com"` | Both `decision` and `decision_by` are bare fields. Dotted form is not supported.                                                                                       |
| `source.tags.value eq "prod"`        | Three dot-separated segments. `tags` matches tag keys only, not tag values.                                                                                            |
| `idp.email co "@example.com"`        | `idp` is valid only when it is declared as a join-spec alias on the workflow's query. See [Filtering by Joined Node Attributes](#filtering-by-joined-node-attributes). |

{% hint style="warning" %}
**One invalid filter blocks every Automation on a Certification.** If any Automation attached to a Certification fails to parse, the Automation run fails for that Certification and no other attached Automations are applied. Validate new filters against a test workflow before attaching them to production Access Reviews.
{% endhint %}

## Filtering by Joined Node Attributes

When an Access Review configuration includes [IdP or HRIS enrichment](/4yItIzMvkpAvMVFAamTf/features/access-reviews/configuration/enrich-idp-hris.md), you can filter on enriched entity attributes in Automations. Reference joined nodes by their **alias** directly (e.g., `idp.attribute`), not using `joined_nodes.idp.attribute`.

For complete guidance on finding aliases, filter syntax, and examples, see [Using Enrichment Data in Automations](/4yItIzMvkpAvMVFAamTf/features/access-reviews/configuration/enrich-idp-hris.md#using-enrichment-data-in-automations).

{% hint style="warning" %}
**Early Access:** Filtering by joined node attributes in Automations is currently in early access. Contact Veza Support for the latest status.
{% endhint %}

## Filtering by Mutable Fields

Mutable filters in Automations use the syntax `previous.decision`, `previous.notes` and `previous.signed_off_state` to refer to historical row data. The possible values are:

* `decision`:
  * "RESULT\_DECISION\_UNKNOWN"
  * "RESULT\_DECISION\_NONE"
  * "RESULT\_DECISION\_ACCEPTED"
  * "RESULT\_DECISION\_REJECTED"
  * "RESULT\_DECISION\_FIXED"
* `notes`: string
* `signed_off_state`:
  * "UNKNOWN"
  * "NOT\_SIGNED\_OFF"
  * "SIGNED\_OFF"

### `action` (Object)

Action the Automation will apply to matching results:

* `decision` (String): Decision code for the action.
* `signed_off_state` (String): Sign off state code.
* `notes` (String): Notes the automation will apply.
* `display_style` (String): Visual indicator to apply to matching rows:
  * `HIGHLIGHT`: Highlight the row
  * `SUGGEST_ACCEPT`: Mark the row as suggested for acceptance
  * `SUGGEST_REJECT`: Mark the row as suggested for rejection
* `display_text` (String): Custom message to show when display\_style is set
* `highlight_color` (String): Hex color code for custom row highlighting (e.g., `#FF0000`, `#00FF00`). Only applies when `display_style` is `HIGHLIGHT`. Must be a valid 6-digit hex color in the format `#RRGGBB`. If omitted, the default highlight color is used.

Note: When using display\_style actions, you cannot set decision, signed\_off\_state, notes, or reviewer\_assignment fields.

Possible decisions and numeric codes are:

* `UNKNOWN` (`0`)
* `NONE` (`1`)
* `ACCEPTED` (`2`)
* `REJECTED` (`3`)
* `FIXED` (`4`)

Signed Off State can be:

* `UNKNOWN_SIGNED_OFF` = 0;
* `NOT_SIGNED_OFF` = 1;
* `SIGNED_OFF` = 2;

### `reviewer_assignment` (Object)

The preview API does not currently support Reviewer assignment.

### Preview API Documentation

Use the endpoints documented below to create and manage automations:

### List Automations

* **Endpoint:** `/api/preview/awf/automations`
* **Method:** GET
* **Description:** Returns all Automations and configuration details.

Returns all [Automations](#automation-object-schema) in a `values` array.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations" method="get" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Update Automation

* **Endpoint:** `/api/preview/awf/automations`
* **Method:** PUT
* **Description:** Updates an existing Automation. The full Automation object is required.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations" method="put" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Create Automation

* **Endpoint:** `/api/preview/awf/automations`
* **Method:** POST
* **Description:** Creates a new Automation.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations" method="post" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Get Automation

* **Endpoint:** `/api/preview/awf/automations/{id}`
* **Method:** GET
* **Description:** Get details for a single Automation by ID.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations/{id}" method="get" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Delete Automation

* **Endpoint:** `/api/preview/awf/automations/{id}`
* **Method:** DELETE
* **Description:** Deletes a specific Automation by its ID.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations/{id}" method="delete" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Attach Automations

* **Endpoint:** `/api/preview/awf/automations:attach`
* **Method:** POST
* **Description:** Enable an Automation for a specific workflow, or all workflows.

Attach one or all Automations to a single workflow by specifying the:

* `id` (String): Single Automation ID.
* `workflow_id` (String): ID of the workflow to associate Automations with.
* `all` (boolean): If `True`, attaches all existing Automations to the Workflow.
* `opt_in` (boolean): If `False` the Automation can be selected when creating a certification. Otherwise, operators can enable it when creating certifications.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations:attach" method="post" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### List attached Workflow Automations

* **Endpoint:** `/api/preview/awf/automations:attached/{workflow_id}`
* **Method:** GET
* **Description:** Returns all Automations eligible to run on Certifications for a given Workflow `id`.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations:attached/{workflow\_id}" method="get" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Detach Automations

* **Endpoint:** `/api/preview/awf/automations:detach`
* **Method:** POST
* **Description:** Detach one or all Automations from an Access Review Workflow.

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/preview/awf/automations:detach" method="post" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-cc6281c14f1540c934b1093e311ed7cf96bd5aea%2Fopenapi.yaml?alt=media)
{% endopenapi %}


---

# 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/developers/api/workflows/automations.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.
