Using the Webhooks API

Overview

In addition to using the Procore Web user interface for configuring Webhooks, you can accomplish this task programmatically using the Webhooks API endpoints. Managing Webhooks using the API involves creating and manipulating Hooks and Triggers. A Hook represents the relationship between a Company/Project and the Notification Endpoint you want to send webhook events to. Triggers belong to a Hook and represent Procore resources that will trigger webhook notifications when those resources are created, updated, or deleted (specified by the Trigger's Event Type).

The Webhooks API endpoints allow you to configure Webhooks programmatically as well as examine webhooks deliveries. These endpoints are documented in the following reference pages:

Webhooks Configuration Using the API

The first step in configuring Webhooks through the API is to create one or more Hooks using the Create Webhooks Hook endpoint. This endpoint provides individual body parameters for specifying the company (company_id) or project (project_id). If you are configuring company-level Webhooks, then you only need to include the company_id parameter in your request body. Similarly, if you are configuring project-level Webhooks then you only need to specify the project_id parameter.

Here is an example request body for creating a Webhooks Hook at the company level:

{ "company_id":5358233, "hook":{ "api_version":"v2", "namespace":"procore", "destination_url":"http://webhooks.mydomain.com", "destination_headers":{ "Authorization":"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9" } } }

In the example above we are creating a Hook for the company associated with "company_id":5358233. In the hook object we specify "v2" for the api_version attribute, "procore" for the namespace attribute (see additional information on namespaces below), we use the destination_url attribute to define the URL for the Notification Endpoint, and the destination_headers attribute to include an Authorization Header.

If we compare the example request body to what we see on the Company Webhooks page in the Procore Web user interface, we find that attributes of the hook object are exposed in the Endpoint Configuration section. See Configure Company Webhooks for additional information.

Endpoint Configuration

To create a project-level Hook you would simply use the project_id parameter rather than the company_id parameter. See Configure Project Webhooks for additional information.

Once you have created a Hook (at either the company or project level), you can add one or more triggers to that Hook using the Create Webhooks Trigger endpoint. This endpoint requires the target_id as a path parameter and the api_version as a request body parameter. In addition, the trigger object is required in the request body with resource_name and event_type attributes.

Here is an example request body for creating a Webhooks Trigger at the company level:

{ "company_id":5358233, "api_version":"v2", "trigger":{ "resource_name":"Company Users", "event_type":"update" } }

In this example, we are creating a Trigger for the update action on the Company Users resource in "company_id":5358233.

If we compare the example request body to what we see on the Company Webhooks page in the Procore Web user interface, we find that the attributes of the trigger object are exposed in the Webhooks Configuration section. See Configure Company Webhooks for additional information.

Trigger Configuration

Common Webhooks API Use Cases

There are a number of common use cases that the Webhooks API is designed to support. These use cases range from single-administrator, single-company Webhook configuration to more complex multi-company scenarios. The most popular Webhooks API use case scenarios are described in the following sections.

Single Company Account Scenario

The most basic use case for the Webhooks API supports Procore client administrators who want to perform Webhook configuration in their company account programmatically rather than through the Procore Web user interface. Some Procore administrators will find it more convenient to use the Webhooks API, especially when they need to configure Webhooks for a large number of projects. The following illustration depicts this scenario.

Basic Webhooks Scenario

In the example above, the Procore administrator for Company A is executing Webhooks API calls to configure company-level and project-level Webhooks within the Company A Procore account.

Multiple Company Account Scenario

Many Procore clients leverage one or more Procore App Marketplace integrations provided by Procore Technology Partners or utilize custom integrations developed by third-party integrators. Under this scenario, Procore Technology Partners and third-party integrators must design their integrations to allow multiple Hooks to exist for the same Company/Project, and to ensure that each Hook can only belong to a single Company/Project. The Webhooks API provides the namespace feature to support this requirement. When the namespace parameter is included in a Webhooks Hook API call, it ensures that the changes resulting from that call are isolated from changes initiated via a call under a different namespace. Procore Technology Partners and third-party integrators therefore define a unique namespace for each application/integration they develop. See Namespace Best Practices below for additional information.

Namespaces allow for more than one App Marketplace integration to interact with a given company account so that one integration can independently perform CRUD operations on Hooks and Triggers without affecting operations performed by another integration. Procore Technology Partners should use a single, unique namespace per app/integration across all Companies/Projects that utilize their integration. The use of namespaces is depicted in the following illustration.

Advanced Webhooks Scenario

This diagram above shows two Procore App Marketplace Applications and a single system integrator interacting with two separate companies running Procore. Each entity has an associated namespace with which Webhooks API CRUD operations are called. The Costcoder application published by Smithsoft is making Webhooks API calls into Company A and Company B using the namespace smithsoft-costcoder. By using this unique namepsace, Costcoder by Smithsoft would be able find their Webhook Hooks for Company A (company_id=1234) by using the List Webhook Hooks call with namespace=smithsoft-costcoder and company_id=1234. The diagram also shows the Bidquick application published by Devpro making Webhooks API calls into Company A and Company B using the namespace devpro-bidquick. Note that both the Costcoder and Bidquick applications are able to manage Webhooks in Project 1 in Company B via the API because they use unique namespaces. Finally, ACME Integrators is working exclusively for Company B and has defined namespace acme-integrators for their use.

Namespace Requirements and Best Practices

As described in the previous section, App Marketplace applications and system integrators use namespaces to isolate their Webhooks API calls from one another. When using the namespace parameter, there are a number of requirements and best practices to be considered:

  • Namespaces are string values restricted to lowercase a-z and dashes (-).
  • Uppercase letters, numbers, and special characters are not supported in namespaces.
  • If no namespace is provided with a call, the default "procore" namespace is assumed.
  • We recommend the format <publisher name>-<application name> for defining namespaces.

Webhooks Deliveries

You can use the List Webhooks Deliveries API endpoint to return a list of the current webhooks events that Procore has delivered (or has attempted to deliver) to your notification server. This provides a convenient alternative to the Procore Web user interface for rertrieving information about webhooks event deliveries. Include the hook_id path parameter to specify the webhooks hook you want to see deliveries for. Use the project_id or company_id query parameter to indicate whether you want to return project or company webhooks deliveries respectively. You can also use the filter[status] query parameter to specify whether you want to retrieve 'any' (all), 'successful', or 'failing' deliveries.

The following table describes the various attributes of the List Webhooks Deliveries response body.

Response Attribute Description
started_at Start time in UTC for the webhooks event delivery.
response_status Status code returned from the delivery attempt. For example, 200 OK, 404 Not Found, etc. Explanations of common status codes are provided in the RESTful API Concepts guide.
response_headers Object containing key/value pairs representing the HTTP header fields included in the response to the webhooks delivery POST call.
response_error Error response message, if applicable.
response_body Content of the HTTP response body resulting from the webhooks delivery POST call.
outcome Result for the webhooks event delivery attempt. Can be one of 'ok', 'retried', or 'failed'.
id Unique identifier for the delivery.
event_id Unique identifier for the webhooks event for which a delivery was attempted.
completed_at Time in UTC when the webhooks event delivery completed.

Filtering the List Webhooks Deliveries Response

Due to the potential large volume of webhooks deliveries your system might be required to consume, you may find it helpful to filter the response from the List Webhooks Deliveries call using the filters[status] query parameter. This query parameter lets you limit the response to 'any' (default), 'successful', or 'failing' webhooks deliveries. Here is the syntax for using the filters[status] query parameter.

https://api.procore.com/vapid/webhooks/hooks/<HOOK_ID>/deliveries?company_id=<COMPANY_ID>&filter[status]=<FILTER_VALUE> where: <HOOK_ID> is the ID for webhook hook <COMPANY_ID> is the ID for company (could also be <PROJECT_ID>) <FILTER_VALUE> is the filter setting - either 'any', 'successful', or 'failing'
example: curl -X GET https://api.procore.com/vapid/webhooks/hooks/12345/deliveries?company_id=987654&filter[status]=failing