Webhooks
NetOrca supports webhooks for Services. When a declaration is submitted and a Change Instance is created for a Service, or during the Change Instance process—for example, if the state of a Change Instance is updated by the Service Owner, NetOrca sends a webhook request to a specified target URL. A common use case for webhooks is triggering an external process such as executing an Ansible playbook.
Create a Webhook
In order to define a webhook for a Service, a POST request must be sent to NetOrca:
POST /v1/external/serviceowner/webhooks/ HTTP/1.1
Content-Type: application/json
Authorization: Token <YOUR_TOKEN>
{
"name": "sample name",
"description": "sample description",
"service": <service_id defined in NetOrca>,
"target_url": "<target_url>",
"authorization": "<auth header, e.g. 'Bearer AwesomeKey'>",
"active": true,
"verify": true,
"timeout": 20,
"change_instance_state": "<Change Instance's state, e.g. PENDING>" or null,
"trigger_wait_time": 5,
"trigger_cooling_time": 5
}
from netorca_sdk import NetOrca
netorca = NetOrca(fqdn=<YOUR_NETORCA_BASE_URL>, api_key=<YOUR_NETORCA_API_KEY>)
data = {
"name": "sample name",
"description": "sample description",
"service": <service_id defined in NetOrca>,
"target_url": "<target_url>",
"authorization": "<auth header, e.g. 'Bearer AwesomeKey'>"
}
webhook = netorca.create_webhook(data=data)

Note
A Service can have only one webhook per change_instance_state.
For example, a Service can have one webhook for PENDING, one for APPROVED and one with change_instance_state set to null,
but not two webhooks for APPROVED.
Webhooks can be listed, retrieved, updated and deleted via the standard REST methods on
/v1/external/serviceowner/webhooks/ and /v1/external/serviceowner/webhooks/<webhook_id>/.
Trigger a Webhook
There are 3 ways to trigger a webhook if it is active.
-
Trigger manually

The response contains the created Webhook Response object in the
SCHEDULEDstate. If the webhook cannot be triggered (e.g. it is inactive, already scheduled, in its cooling time or rate limited), a400 Bad Requestis returned with the reason. -
Trigger on a specific Change Instance state
If the webhook’s
change_instance_statefield is set, the webhook is automatically triggered when a Change Instance of the Service is created in, or transitions to, that state. -
Trigger on every Change Instance event
If the webhook’s
change_instance_statefield is set tonull, it is triggered whenever a Change Instance of the Service is created (i.e. when a Consumer submits a declaration) or its state changes.
When a webhook is triggered, an HTTP POST request is sent to the target URL with the details of the Service:
POST <webhook.target_url> HTTP/1.1
Content-Type: application/json
Authorization: <webhook.authorization>
{
"id": <service_id>,
"name": "<service_name>",
"owner": {
"id": <owner_id>,
"name": "<service_owner_name>"
},
"state": ""
}
The request does not contain the Change Instance that caused the trigger.
The external process is expected to query NetOrca for the Change Instances it needs to handle,
e.g. the APPROVED Change Instances of the Service.
Webhook Responses
When a webhook is triggered, NetOrca creates a corresponding response object in its database. This object records the HTTP status code and response body returned by the webhook’s target URL. Since webhook triggers are handled asynchronously, the response data may not be immediately available. To manage this, each response object includes a state that reflects the current progress of the HTTP request.
The possible state values are:
| State | Description |
|---|---|
SCHEDULED |
The Webhook HTTP request is queued and waiting to be sent (see trigger_wait_time). |
WAITING_FOR_RESPONSE |
The Webhook HTTP request was sent and is awaiting a response. |
OK |
The target URL responded with 200 or 201. |
FAILED |
The target URL responded with any other status code, or the request failed (connection error, timeout, SSL error, etc.). |
If the request fails without a response from the target URL, status_code is null and body contains the error, e.g. {"error": "Timeout error occurred"}.
Responses that remain in SCHEDULED or WAITING_FOR_RESPONSE for too long are automatically marked as FAILED.
To see the list of Webhook Responses:
GET /v1/external/serviceowner/webhook_responses/ HTTP/1.1
Content-Type: application/json
Authorization: Token <YOUR_TOKEN>
Trigger Limitations
A webhook is not triggered if any of the following applies. When triggered manually, the request fails with the corresponding error; when triggered by a Change Instance, the trigger is silently skipped.
- Inactive: the webhook's
activefield isfalse. - Wait time (
trigger_wait_time): a trigger is already scheduled. Each trigger is delayed bytrigger_wait_timeseconds before the request is sent, and any further trigger within that window is skipped. This is useful when multiple events occur close together—such as merging several merge requests back-to-back or approving many Change Instances at once—as it batches them into a single webhook request. - Cooling time (
trigger_cooling_time): the webhook was triggered less thantrigger_cooling_timeseconds ago. This prevents redundant triggers immediately after a webhook request. - Rate limit: the webhook has already been triggered the maximum number of times in the last minute. This limit is configured by NetOrca Administrators via
webhook_rate_limit_per_minutein General Settings (default5).
In addition, NetOrca Administrators can limit the number of webhook responses retained per webhook via webhook_response_rate_limit (default 10).
Once the limit is reached, the oldest completed responses are automatically removed.