Webhooks
Receive secure, projection-ready RoadOps changes in your application.
Webhooks deliver RoadOps changes to your service after the required read models have finished projecting. Create an endpoint in the signed-in Developer Portal under Webhooks, or manage it through the Developer API with the webhook:read and webhook:write scopes.
Each webhook can bind the same endpoint to one or more teams. The creator must be an active member of every selected team and must currently hold both the membership permission and Developer API read scope required by each selected event type. Personal access tokens and OAuth access tokens also need the resource read scopes listed by GET /v1/webhook-event-types; read:all and write:all do not grant webhook management.
Delivery model
Because RoadOps is eventually consistent, a webhook is triggered only after the originating change has reached the projected read models used by the Developer API.
The payload contains the current Developer API read representation of the resource at delivery time. It is deliberately not a historical event snapshot. If later changes project before delivery, data can be newer than event.aggregateVersion; use event.cursor for ordering and the payload id for deduplication. Deleted resources are the exception: data is a deletion tombstone because the current record no longer exists.
resource.url identifies the matching Developer API read route when one exists. A receiver can refetch that route when it needs the latest state after processing.
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"payloadVersion": "1",
"type": "day.updated",
"createdAt": "2026-08-18T14:20:00.000Z",
"team": { "id": "2c1f89be-4067-4a84-b8f8-65ec268f6016" },
"event": {
"id": "80eb12ce-39de-4480-8a73-e301dad654e7",
"aggregateId": "bbadc032-8439-43eb-8880-ddbabec411b4",
"aggregateVersion": 4,
"cursor": 9124
},
"resource": {
"type": "day",
"id": "bbadc032-8439-43eb-8880-ddbabec411b4",
"url": "/v1/teams/2c1f89be-4067-4a84-b8f8-65ec268f6016/days/bbadc032-8439-43eb-8880-ddbabec411b4"
},
"changes": ["name"],
"data": {
"id": "bbadc032-8439-43eb-8880-ddbabec411b4",
"teamId": "2c1f89be-4067-4a84-b8f8-65ec268f6016",
"name": "Show Day",
"date": "2026-08-19",
"version": 5,
"cursor": 9130
}
}Access at delivery time
Before every attempt, RoadOps rechecks the webhook owner, active team membership, resolved membership permissions, record visibility, ownership rules, and private-note rules. Inaccessible records are suppressed without sending their contents. Removing the owner from a team suspends that team binding; deleting the owner account removes their webhook endpoints.