# Send REST Request

Makes HTTP requests to external APIs and services as part of provisioning workflows. This action enables integration with custom applications, webhooks, and REST-based services that support identity management operations.

**Example Use Cases:**

* Notify external systems when users are created or updated in target systems
* Trigger custom provisioning workflows in third-party applications
* Send identity data to SCIM endpoints for user synchronization
* Create service desk tickets for manual provisioning steps
* Execute webhooks to coordinate multi-system workflows
* Extract response data (like user IDs) from external systems for use in downstream actions

| Setting                           | Description                                                                                                                                                                                                                                                                                  |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Webhook URL                       | Target REST endpoint URL. Supports variable substitution using `{attribute_name}` syntax in URL path and query parameters                                                                                                                                                                    |
| HTTP Method                       | Request method: GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS. Methods are case-insensitive and automatically converted to uppercase. POST, PUT, and PATCH require a JSON payload                                                                                                          |
| Authorization Header              | Required authentication header (e.g., `Bearer <token>`, `X-API-Key: <key>`, or custom authorization format)                                                                                                                                                                                  |
| JSON Payload                      | Request body in JSON format. Supports [transformer syntax](/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/transformers.md) for attribute substitution: `{"user": "{name}", "email": "{email}"}`                                                                                         |
| Timeout                           | Maximum wait time in seconds for the request to complete (default: 60 seconds)                                                                                                                                                                                                               |
| Only Send if Any Upstream Changes | When enabled, the request is only executed if a previous action in the workflow modified or created resources                                                                                                                                                                                |
| Add Response to Output Entities   | Extract entity data from the API response to make available for downstream actions                                                                                                                                                                                                           |
| Output Entity Type                | Type of entity to create from response (required if "Add Response to Output Entities" is enabled)                                                                                                                                                                                            |
| Response Entity Attribute         | JSON path to extract from response using dot notation (e.g., `result` extracts `response.result`, `data.user` extracts `response.data.user`)                                                                                                                                                 |
| Response ID Attribute             | Attribute name containing the entity identifier in the response (defaults to `id`)                                                                                                                                                                                                           |
| Response Name Attribute           | Attribute name containing the entity display name in the response (defaults to `name`)                                                                                                                                                                                                       |
| Execute from Insight Point        | Optional data source to route the request through an Insight Point agent. Leave empty to execute from the control plane. See [Custom Application with Send REST Payload](/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/policies-workflows/oaa-send-rest-payload.md) for configuration. |

{% hint style="info" %}
**Data Source Selection** (Optional): Select a data source to route the REST request through an Insight Point instead of the Veza control plane. Use this to reach endpoints that are not publicly accessible, such as internal APIs behind a firewall. The dropdown only shows Custom Providers configured with `external_lifecycle_management_type: SEND_REST_PAYLOAD`. If no data sources appear, see [Custom Application with Send REST Payload](/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/policies-workflows/oaa-send-rest-payload.md) for configuration.

**TLS certificates**: If the target API uses an internal or self-signed CA certificate, the Insight Point must trust that CA or the request will fail with `x509: certificate signed by unknown authority`. Configure the CA certificate in the Insight Point's trust store before enabling Insight Point routing. See [Custom Certificate Configuration](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/insight-point/ova-v2.md#custom-certificate-configuration) (OVA) or [Using Custom Certificates](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/insight-point/insight-point-install-script.md#using-custom-certificates) (install script).
{% endhint %}

## Variable Substitution

When constructing the webhook URL and JSON payload, you can reference identity attributes using curly brace syntax. Two sources of attributes are available specifically for this URL and payload context:

* **Source-of-identity (SOI) attributes**: Attributes from the identity source triggering the workflow (e.g., Workday worker fields, Okta user attributes).
* **Sync Identities output entity attributes**: When a Sync Identities action precedes this action in the same workflow, attributes from the provisioned or updated target user (such as Active Directory user attributes) are also available. See [Standard Active Directory attributes available for substitution](#standard-active-directory-attributes-available-for-substitution) below.

```
URL: https://api.example.com/users/{email}/provision?dept={department}
Payload: {"name": "{first_name} {last_name}", "role": "{job_title | UPPER}"}
```

Available transformations include `UPPER`, `LOWER`, `TRIM`, and accessing nested attributes with dot notation, such as `{Manager.email}`. See [Transformers](/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/transformers.md) for complete transformation syntax.

> **Note**: If any placeholder in the URL or payload cannot be resolved (e.g., due to missing attributes), the entire transformation is skipped and the original URL is used without any substitution. The system logs a warning for troubleshooting. Ensure all referenced attributes exist in the source of identity to enable proper variable substitution.

## Form field substitution (Access Requests only)

When a Send REST Request action is configured as part of an Access Request [catalog definition](/4yItIzMvkpAvMVFAamTf/features/access-hub/configuration.md#creating-a-send-rest-payload-catalog-definition), the JSON payload can reference form field values submitted by the requester. This enables dynamic payloads where the requester provides values (such as a role name or resource ID) at request time, and those values are injected into the API call.

Use the `{$form_field.field_name}` syntax in the JSON payload, where `field_name` matches a field defined in the catalog definition's form fields.

To configure form field substitution:

1. Create a Send REST Request action in a provisioning policy with placeholders in the JSON payload:

   ```json
   {"roleName": "{$form_field.role_name}", "roleId": "{$form_field.role_id}"}
   ```
2. Create a Send REST Payload [catalog definition](/4yItIzMvkpAvMVFAamTf/features/access-hub/configuration.md#creating-a-send-rest-payload-catalog-definition) and add form fields with names that match the placeholders (e.g., `role_name`, `role_id`).
3. When a user submits an access request using this catalog definition, they fill in the form fields. The submitted values replace the corresponding `{$form_field.*}` placeholders in the payload before the REST call is made.

Form field substitution applies to the JSON payload only. It does not apply to the webhook URL or authorization header. Field names must contain only letters, numbers, and underscores (`role_name` is valid, `role-name` is not). If a placeholder references a field that was not provided in the access request, the placeholder is left unchanged in the payload.

{% hint style="info" %}
Form field substitution and identity attribute substitution can be combined in the same payload. For example: `{"user": "{email}", "role": "{$form_field.role_name}"}` substitutes the identity's email from the source of identity and the role name from the access request form.
{% endhint %}

## Standard Active Directory attributes available for substitution

The following attributes are populated on the sync\_identities output entity for Active Directory integrations and can be used in variable substitutions:

| Attribute key         | Description                            |
| --------------------- | -------------------------------------- |
| `email`               | Primary email address (`mail`)         |
| `given_name`          | First name (`givenName`)               |
| `sur_name`            | Surname (last name) (`sn`)             |
| `display_name`        | Display name (`displayName`)           |
| `department`          | Department                             |
| `title`               | Job title                              |
| `user_principal_name` | UPN (login name) (`userPrincipalName`) |
| `street_address`      | Street address (`streetAddress`)       |

Custom properties defined in the integration configuration are also available, using the key `customprop_<property_name>` (where `<property_name>` is the property's format name as configured).

## Response Handling

When "Add Response to Output Entities" is enabled, the action parses JSON responses and extracts specified entity data. This enables chaining actions where one API call creates a resource and returns an identifier that subsequent actions can reference.

For example, if a user creation API returns:

```json
{
  "result": {
    "user_id": "12345",
    "display_name": "John Doe"
  }
}
```

Configure the action with:

* Response Entity Attribute: `result`
* Response ID Attribute: `user_id`
* Response Name Attribute: `display_name`

The extracted entity becomes available to downstream workflow actions.

## HTTP Method Guidelines

* **GET**: Query operations, typically without payload; use for checking resource state or retrieving data. Does not set workflow change flags
* **POST**: Create new resources; requires JSON payload; sets both `AnyCreated` and `AnyChanges` flags that can trigger downstream actions with "Only Send if Any Upstream Changes" enabled
* **PUT**: Replace entire resources; requires JSON payload; sets `AnyChanges` flag
* **PATCH**: Partially update resources; requires JSON payload; sets `AnyChanges` flag
* **DELETE**: Remove resources; payload optional; sets `AnyChanges` flag
* **HEAD**: Metadata query without response body; payload optional; sets `AnyChanges` flag
* **OPTIONS**: Describes communication options for the target resource; payload optional; sets `AnyChanges` flag

> **Workflow Integration**: The `AnyCreated` and `AnyChanges` flags enable conditional workflow execution. Actions configured with "Only Send if Any Upstream Changes" will only execute when a previous action has set these flags, allowing you to build sophisticated conditional workflows (e.g., only send a notification webhook if a user was actually created, not just updated).

## Authentication Patterns

The authorization header supports common authentication methods:

* **No Authentication**: Leave the authorization header empty when connecting to endpoints that don't require credentials, such as internal services or pre-authenticated URLs
* **Bearer Token**: `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`
* **API Key**: `X-API-Key: secret-key-123` or `Authorization: ApiKey sk-prod-xyz`
* **Custom Headers**: Any header format your API requires

{% hint style="info" %}
The "No Auth" option is useful for internal microservices, pre-authenticated webhook URLs, or endpoints behind a VPN that handle authentication at the network level.
{% endhint %}

## Limitations

* Only JSON payloads are supported (no XML, form-data, or other formats)
* Authentication must be header-based (OAuth flows requiring user interaction are not supported)
* Response parsing requires valid JSON if "Add Response to Output Entities" is enabled
* Timeout applies to entire request; no automatic retry on failure
* POST, PUT, and PATCH methods require non-empty, valid JSON payloads

<details>

<summary>Example: Suspend Okta users via REST API</summary>

The Send REST Request action can call Okta lifecycle APIs to suspend users, enabling workflows that handle leave of absence (LOA) scenarios before native Suspend action support is available.

**Configuration:**

| Setting                  | Value                                                                                                                               |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| **Webhook URL**          | `https://{your-okta-domain}/api/v1/users/{employee_id \| FROM_ENTITY_ATTRIBUTE,"OktaUser","employee_id","login"}/lifecycle/suspend` |
| **HTTP Method**          | `POST`                                                                                                                              |
| **Authorization Header** | `SSWS {your-okta-api-token}`                                                                                                        |
| **JSON Payload**         | `{}`                                                                                                                                |

**Key notes:**

* **User identification**: Okta's suspend API requires the user's Okta ID or login. Use the `FROM_ENTITY_ATTRIBUTE` transformer to look up the Okta login from the Authorization Graph based on a source attribute like `employee_id`.
* **Authorization format**: Okta API tokens must be prefixed with `SSWS` (e.g., `SSWS 00abcd1234...`), not `Bearer`.
* **Empty payload**: The suspend endpoint requires a POST with an empty JSON object `{}` as the payload.

**Example workflow condition:**

To suspend users when their SOI lifecycle status changes to a leave state:

```scim
lifecycle_status eq "Leave" or lifecycle_status eq "Parental Leave" or lifecycle_status eq "Garden Leave"
```

**Unsuspending users**: To reactivate suspended users, create a separate workflow condition with the unsuspend endpoint:

```
https://{your-okta-domain}/api/v1/users/{employee_id | FROM_ENTITY_ATTRIBUTE,"OktaUser","employee_id","login"}/lifecycle/unsuspend
```

This approach is used when the SOI lifecycle status changes back to an active state (e.g., `lifecycle_status eq "Employed"`).

</details>


---

# Agent Instructions: 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:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/features/lifecycle-management/policies-workflows/actions/send-rest-request.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
