- Getting started
- Best practices
- Tenant
- Actions
- Folders Context
- Automations
- Processes
- Jobs
- Triggers
- Logs
- Monitoring
- Queues
- Assets
- Storage Buckets
- Test Suite - Orchestrator
- Action Catalogs
- Profile
- System Administrator
- Identity Server
- Authentication
- Other Configurations
- Integrations
- Classic Robots
- Troubleshooting
Orchestrator User Guide
Webhooks
Webhooks enable you to better integrate your UiPath automation with your entire application ecosystem. You can subscribe to Orchestrator events and send them to any external DCM, BPM, or CRM solution and inform different users, for example, that there is a new queue item which can be processed, a trigger has failed, or a process has been updated.
Webhooks allow external systems to subscribe and listen to different types of Orchestrator events. The Webhooks page enables you to easily set them up, as well as view the ones that have been previously created. You can also disable webhooks, search for a specific one, edit or delete them.
Events are available for jobs, robots, queues, queue items, processes, and triggers. For the full list of event types and a few examples, please check this page.
Each event sends a payload to a specified URL containing information. Some properties are common for all, while others are particular to each event type.
Property Name |
Property Type |
Description and Example |
---|---|---|
Type |
string |
The event type that triggered the notification. This property is displayed for all types of events. Example:
|
EventId |
string |
An identifier uniquely generated for each event when it occurred. This property is displayed for all types of events. Example:
|
Timestamp |
RFC 8601 date |
The date and time at which the event was generated. This property is displayed for all types of events. Example:
|
TenantId |
integer |
The id of the tenant on which the event was generated. The default tenant is 1. This property is displayed for all types of events. Example:
|
UserId |
integer |
The user id whose action triggered the event. This parameter is not displayed if the event is triggered by either a Robot or a trigger. This property is displayed for all types of events. Example:
|
FolderId |
integer |
The id of the folder in which the event was generated. This parameter is not displayed for events triggered by modern robots. Example:
|
To perform various operations on the Webhooks page, you need to be granted the corresponding permissions on webhooks:
- View - Enables you to view webhooks and their details, as well as retrieve them using the API, send a ping request, or get the list of all the events to which a webhook can subscribe.
- Create - This permission enables you to add new webhooks. Please note that you also require View permissions.
- Edit - Grants you the right to edit webhooks from the UI or by using the API. Please note that you also require View permissions.
- Delete - A permission that enables you to delete webhooks. Please note that you also require View permissions.
X-UiPath-Signature
HTTP header.
Client apps that receive Orchestrator requests must check the requests' authenticity. The request signing follows the following pattern:
- The client app receives a webhook request from Orchestrator;
- The client app computes a signature based on the request;
-
The client app tries to match the signature it computed with the request signature:
- If the signatures do not match, the client app should not process the request.
- If the signatures match, the client app should process the request.
Computing the signature should be done as follows:
- Retrieve the
X-UiPath-Signature
HTTP header. - To obtain the raw signature bytes, decode the value of the header from Base64.
-
Retrieve the raw request body.
Note: Orchestrator requests are always encoded using UTF-8. - Compute the hash using SHA256 and the signing key (UTF-8 encoded).
-
Compare the computed signature to the value from
X-UiPath-Signature
HTTP header:- If the signatures do not match, do not process the request.
- If the signatures match, the client app should process the request.
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
return false;
var orchestratorSignature = Convert.FromBase64String(headerValues.First());
using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
{
var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
return ByteArrayEquals(orchestratorSignature, computedSignature);
}
}
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
return false;
var orchestratorSignature = Convert.FromBase64String(headerValues.First());
using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
{
var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
return ByteArrayEquals(orchestratorSignature, computedSignature);
}
}
const { createServer } = require('http');
const { createHmac } = require('crypto');
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
expectedSignature == null || createHmac('sha256', secret)
.update(body)
.digest('base64') === expectedSignature
const server = createServer((req, resp) => {
let body = new Buffer([])
req.on('data', chunk => body = Buffer.concat([body, chunk]))
req.on('end', () => {
if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
console.error('Invalid signature')
resp.statusCode = 401 // Unauthorized
} else {
let payload = JSON.parse(body.toString('utf8'))
// Process request
console.log(payload)
resp.statusCode = 202 // Accepted
}
resp.end()
})
})
server.listen(PORT)
const { createServer } = require('http');
const { createHmac } = require('crypto');
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
expectedSignature == null || createHmac('sha256', secret)
.update(body)
.digest('base64') === expectedSignature
const server = createServer((req, resp) => {
let body = new Buffer([])
req.on('data', chunk => body = Buffer.concat([body, chunk]))
req.on('end', () => {
if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
console.error('Invalid signature')
resp.statusCode = 401 // Unauthorized
} else {
let payload = JSON.parse(body.toString('utf8'))
// Process request
console.log(payload)
resp.statusCode = 202 // Accepted
}
resp.end()
})
})
server.listen(PORT)