Webhooks
A webhook lets FlexiProject notify an external system the moment something happens in your organization. Instead of polling the API over and over to see whether anything changed, your system gets an HTTP request with the event data right after the event occurs.
One webhook links one event with one receiver address. To send two different events to the same address, or the same event to two systems, create two webhooks.
You configure webhooks in System settings > Webhooks. The section is available to system administrators (see Users and permissions). To read data through another channel, use the API.
Events
FlexiProject reports four events. Each webhook listens to exactly one of them, chosen from the Event list.

| Event | When FlexiProject sends the request | Event-specific data |
|---|---|---|
| Project created | A new project came into being, in any way: from scratch, from a template, by cloning, by importing an MS Project or Excel file, or with the help of AI. | projectId, projectName, createdAt |
| Project deleted | A project was deleted. | projectId, projectName |
| Approval started | A change request was submitted for approval and its approval path started. | changeRequestId, changeRequestName, projectId, projectName, date |
| Approval completed | The approval path ended with a decision: approval, rejection or cancellation. | changeRequestId, changeRequestName, projectId, projectName, decisionDate, status |
Every request also carries the event name (event), the moment it was generated (timestamp), and the identifier (userId) and e-mail address (userEmail) of the user whose action triggered it. The format of the whole request is described in HTTP request format. Approvals are described in Approvals.
Webhook configuration
Webhook list
The Webhooks page shows all the organization’s webhooks in three columns: Event, Receiver URL and Description. When nothing is defined, the message No webhooks appears.

Adding a webhook
- Click the add button above the list. The Add webhook window opens.
- Choose the Event. Project created is set by default.
- Enter the Receiver URL — the address FlexiProject sends the request to. The field is required and needs the full address including the protocol, for example
https://example.com/hooks/flexiproject. An incomplete address is rejected with a data processing error message. - Optionally, enter a Description — a note for your team, visible only on the list.
- Click Save.
Secret
Right after saving, the Secret window appears with the message: The webhook has been created. Below is the secret, which will be shown only once. Copy it and store it in a safe place. The Copy button puts the value on the clipboard (message Copied to clipboard), and you save it in the receiving system. The secret signs every request, so the receiver can confirm that the request comes from FlexiProject (see HTTP request format).
After you close the window, the full value is no longer available anywhere in the application. In a webhook opened later, the Secret field shows only the first and last four characters with asterisks in the middle; the field cannot be edited.
Editing a webhook
Click an event name on the list to open the Edit webhook window. You change the event, the receiver address and the description there, then Save. The secret stays unchanged — editing never issues a new one. Closing the window with unsaved changes brings up the question Do you want to move on and abandon change?.
Testing a webhook
The Test button is in the edit window of a saved webhook. It sends a request in the format of the chosen event, filled with sample data (for example a project named Test Project), to the configured address, and confirms with Test request sent successfully. The message confirms that the request was sent, not that the receiver accepted it — check the result on the receiving side.
Deleting a webhook
The Delete button in the webhook window needs confirmation of the question Are you sure you want to delete this webhook?. From then on the event is no longer sent to that address. Deletion cannot be undone; resuming delivery means a new webhook, and so a new secret.
HTTP request format
FlexiProject sends a POST request with a JSON body to the configured address.
Headers
| Header | Content |
|---|---|
X-FlexiProject-Event |
The event name: ProjectCreated, ProjectDeleted, AcceptanceStarted or AcceptanceCompleted. |
X-FlexiProject-Delivery |
The delivery identifier. It stays the same across all retries of the same event, so you can recognize duplicates by it. |
X-FlexiProject-Timestamp |
The moment the request was sent. |
X-FlexiProject-Signature |
The signature of the request body in the form sha256=<value>. |
Verifying the signature
The signature is an HMAC-SHA256 of the raw request body, computed with the webhook secret as the key and written in lower-case hexadecimal. On the receiving side, compute the same value from the received body and compare it with the part of the X-FlexiProject-Signature header after sha256=. If the values differ, reject the request — it does not come from your organization in FlexiProject.
Sample body
{
"projectId": "6712f0a1c3d4e5f601234567",
"projectName": "Warehouse modernization",
"createdAt": "2026-09-21T08:14:02Z",
"userId": "a3f1c7de-1b20-4f9e-9a55-0c2d8e7b41aa",
"userEmail": "anna.kowalska@example.com",
"event": "ProjectCreated",
"timestamp": "2026-09-21T08:14:02Z"
}
Response and retries
Reply with a success status (2xx) as soon as you accept the request. Any other response, or none, counts as a failed delivery.
A failed delivery is retried automatically with a growing interval: after 1, 2, 4, 8, 16, 32, 64, 128, 256 and 512 minutes. The attempts spread over roughly seventeen hours, so a receiver that is unavailable for a while does not lose the event. Every attempt repeats the same X-FlexiProject-Delivery value, so prepare your handling for receiving the same event more than once.