Introduction to Webhooks
Learn how Procore notifies your app in real time with webhooks.
Overview
A webhook is an HTTP request that one system sends to another when a specific event happens. Webhooks let systems share updates in real time without polling.
In Procore, external systems can subscribe to events (create, update, delete) for supported resources. For example, an integration can be notified when a new RFI is created.
Why use webhooks
- Get near real‑time updates without polling.
- Automate workflows in external systems.
- Reduce API calls and infrastructure cost.
How Webhooks Work
- An event occurs in Procore (Web, Mobile, or API).
- If webhooks are configured at the company or project level, Procore sends an HTTPS
POST
to your endpoint with an event object in the JSON body. - For creates and updates, your service can make a follow‑up
GET
to the Procore API to retrieve details for the changed resource.
Access and Authentication
Procore supports a dedicated permissions set for Webhooks called Webhooks API. This is the recommended permission set at the Company and Project level to create, list, edit and delete Hooks or Triggers.
Permissions
- The Webhooks API permission must be Standard for your data connector component.
- By default, the permissions are set to None.
Webhook Event Payload
When you configure a webhook, choose a payload format for event deliveries. In current v1.0 APIs this is called api_version
; in future versions it will be payload_version
. This setting controls the JSON schema of each delivered event. Use the versions below to pick the right option.
Each webhook delivery includes an event object with the fields below (legacy payload format shown):
Event property | Description |
---|---|
api_version |
Procore API version. |
company_id |
Company where the event occurred. |
event_type |
create , update , or delete . |
id |
Event ID. |
metadata |
Context about the event (source app, user, etc.). |
project_id |
Project where the event occurred. |
resource_id |
ID of the changed resource. |
resource_name |
Name of the changed resource. |
timestamp |
UTC time when the event occurred. |
ulid |
26‑character unique identifier. |
user_id |
User who initiated the event. |
Events are sent in one or more deliveries to your endpoint. Deliveries include additional fields such as response status and outcome. For details, see Using the Webhooks API.
Payload Formats
Choose a version below.
Version v2.0 (legacy)
This is our legacy payload format and is used for most existing webhook deliveries.
{
"id": 123456789,
"ulid": "0A1B2C3D4F5G6H7I8J9K0LMN",
"timestamp": "2025-02-06T23:34:12.246562Z",
"metadata": {
"source_user_id": 987654321,
"source_project_id": 2468013579,
"source_operation_id": null,
"source_company_id": 1357908642,
"source_application_id": null
},
"user_id": 987654321,
"company_id": 1357908642,
"project_id": 2468013579,
"api_version": "v2.0",
"event_type": "update",
"resource_name": "RFIs",
"resource_id": 54321
}
Version v3.0
v3.0 adds arelated_resources
array. It is usually empty; certain line item resources include a related object. Example for Direct Cost Line Items:
{
"id": 123456789,
"ulid": "0A1B2C3D4F5G6H7I8J9K0LMN",
"timestamp": "2025-02-06T23:34:12.246562Z",
"metadata": {
"source_user_id": 987654321,
"source_project_id": 2468013579,
"source_operation_id": null,
"source_company_id": 1357908642,
"source_application_id": null
},
"user_id": 987654321,
"company_id": 1357908642,
"project_id": 2468013579,
"api_version": "v3.0",
"event_type": "update",
"resource_name": "Direct Cost Line Items",
"resource_id": 379913,
"related_resources": [
{ "id": 1234, "name": "Direct Costs" }
]
}
Version v4.0
v4.0 simplifies the schema and changes some key types. All IDs are strings.event_type
is renamed to reason
and can include more than create, update, and delete. Hooks using v4.0 can also deliver additional resource types.
{
"id": "01JMYXMZRBVKK0PC6XS8SA4QRE",
"timestamp": "2025-02-25T16:04:43.619085Z",
"reason": "update",
"company_id": "8",
"project_id": "6778",
"user_id": "5447",
"resource_type": "Direct Cost Line Items",
"resource_id": "379913"
}
Set Up Your Endpoint
Your notification endpoint must:
- Be publicly accessible over HTTPS.
- Accept
POST
requests withapplication/json
and parse the body. - Return a
2xx
status on success (send it quickly; process work asynchronously). - Match the endpoint URL you configure on the Webhooks page.
Expected request/response
HTTP method | Content‑Type | Body | Successful response |
---|---|---|---|
POST |
application/json |
Event JSON | 200 OK or 204 No Content |
Reliability and Retries
Design your service to be resilient:
- Duplicates: A delivery for the same event can arrive more than once. Make processing idempotent (for example, track processed events by
ulid
or eventid
). - Respond fast: Return a
2xx
as soon as you receive the event, then handle downstream work asynchronously. Procore’s request timeout is 5 seconds after a connection is established. - Retry/backoff: On failures (non‑
2xx
, timeout, or connection issues), deliveries pause and retry with exponential backoff (starting at 1 second, up to 1 hour). After 12 hours of retries, the queue is flushed and queued events are marked discarded. A successful delivery resets the counters and normal delivery resumes.