Webhooks and event-driven Drupal integrations
A product page can stay published for months while its price, stock, and lead time change several times a day. If a connected buying assistant still sees yesterday’s availability, well-structured content won’t prevent a bad recommendation. A Drupal webhooks module can help by notifying connected systems when decision-making facts change, instead of making them repeatedly scan the full API.
The notification is only the beginning. To keep those facts current, you need to decide what to send, how to handle failed deliveries, and which caches and indexes need refreshing.
Here’s how to plan that flow without slowing down editors or leaving your team guessing when an update goes missing.
In this article:
- When does a webhook make more sense than polling?
- Which events are worth sending, and what belongs in the payload?
- How do you choose a Drupal webhooks module?
- How will delivery survive timeouts, duplicates, and outages?
- How do signatures protect a webhook?
- What changes when an ERP or PIM pushes into Drupal?
- Which caches need attention after a data change?
- How will the team spot and recover failed updates?
When does a webhook make more sense than polling?
Suppose your site lists industrial components. A product’s lead time changes from two days to three weeks, but your connected retrieval system won’t scan the catalog again until tonight. Until then, an assistant using that system may recommend the product based on an outdated delivery promise.
A webhook shortens that gap:
- The source records the new lead time.
- It sends an HTTP notification to a registered receiving endpoint.
- The receiver updates its stored facts or fetches the changed resource.
The benefit is targeted work. Instead of downloading thousands of unchanged products to find one update, the consumer learns which product needs attention.
Polling still has a place. A daily reference-data update may not justify queues, signing secrets, and delivery monitoring. Where an API supports incremental queries or conditional requests, polling can also avoid repeated full scans.
Choose webhooks when the cost of stale data outweighs the cost of operating the delivery flow. Keep periodic reconciliation alongside them to catch missed updates.
For a broader view of planning outbound and inbound connections, see How to Perform a Drupal Integration with Other Enterprise Systems?.
For AI-connected websites, the boundary matters: Drupal can notify a search index, product feed service, or retrieval system you control. It cannot force an external AI assistant to refresh its knowledge. Even your own consumer needs time to process the event and make the new facts available.
Which events are worth sending, and what belongs in the payload?
Start with changes that affect a downstream decision. Sending every editorial save creates noise and makes failures harder to investigate.
Useful events often include:
| Event | Why a consumer needs it | Event-specific data |
|---|---|---|
| Price changed | Update comparisons, quotes, or recommendations | Amount, currency, unit, and pricing context |
| Availability changed | Avoid recommending unavailable stock | Availability status, quantity where appropriate, and location |
| Lead time changed | Refresh delivery expectations | Duration or date range, unit, and applicable location |
| Content published | Add newly public content to a feed or index | Resource identifier, language, and resource URL |
| Content unpublished or deleted | Remove content from downstream results | Stable identifier, language or scope, and removal action |
For every event, use a shared envelope: a unique event ID, event type, source, resource UUID, occurrence time, and schema version. Include a resource version or sequence number where the source can provide one.
Keep two versions distinct. The schema version describes the payload format. The resource version tells the consumer whether this update is newer than another update for the same resource.
For example, an illustrative price event could look like this:
{
"event_id": "ad0d72db-88e6-47c8-bb8d-7eef69e3ba70",
"event_type": "product.price_changed",
"source": "catalog",
"occurred_at": "2026-05-12T09:30:00Z",
"schema_version": 1,
"resource_uuid": "74955cae-3913-41eb-bddc-a4be47ee5342",
"resource_version": 184,
"language": "en",
"resource_url": "https://catalog.example/api/products/74955cae-3913-41eb-bddc-a4be47ee5342",
"changed_fields": ["price"],
"data": {
"amount": "129.00",
"currency": "USD",
"pricing_context": "public",
"unit": "item",
"tax_included": false
}
}The URL and field names here illustrate a contract, not a standard Drupal endpoint.
You have two useful payload patterns:
- Compact notification: Send identifiers, changed fields, and an authenticated resource URL. The consumer fetches the current state.
- Snapshot: Include the values the consumer needs. This avoids a follow-up request but sends more data and demands careful access controls.
Choose based on the job. A search index may only need the latest published state. A consumer recording price transitions may need each event’s snapshot.
Consumers that follow compact notifications often fetch through Headless CMS: how to expose data using REST API and JSON API modules.
Deletion needs special care. Include enough identity and scope information for the consumer to remove its copy, because fetching the deleted resource will no longer work. For translated content, distinguish removing one language version from removing the entire resource.
How do you choose a Drupal webhooks module?
Write down the required behavior before comparing projects. A module that sends a POST request after an entity save may cover a simple notification, but that alone doesn’t establish reliable delivery.
Drupal’s internal hooks and events let code respond to application activity. They do not automatically provide durable queues, retries, external signatures, or delivery histories.
Workflow tools such as n8n can sit on the receiving side of outbound Drupal events; see Drupal and n8n integration: connect forms, content, and business systems for a practical routing pattern.
Evaluate a candidate against your actual flow:
| Capability | What to verify |
|---|---|
| Direction | Does it send outbound notifications, accept inbound requests, or both? |
| Event selection | Can it filter entity types, fields, languages, and publication changes? |
| Payload mapping | Can it produce a stable, versioned payload with the right access boundaries? |
| Background delivery | Does it store work durably and support workers? |
| Failure handling | How does it handle timeouts, rate limits, retries, and exhausted attempts? |
| Security | Does it support the required signing scheme and secret rotation? |
| Visibility | Can the team inspect delivery attempts and replay failures? |
Check supported Drupal versions, maintenance activity, documentation, and Drupal security advisory coverage. For a Drupal 11 project, verify compatibility for the release you plan to install, including its dependencies.
Ask for evidence. Documentation and a small failure test will tell you more than a feature label.
Separate what the module provides from what your team will build or configure. A maintained Open Source module may supply event selection and payload mapping while an integration service handles delivery. Custom Drupal code may make sense when the contract is narrow but the reliability requirements are strict.
The goal is a predictable operating model, not the longest feature list.
How will delivery survive timeouts, duplicates, and outages?
An unavailable consumer shouldn’t leave an editor waiting for a save operation to finish. Keep remote HTTP calls out of the save request.
Instead, record outbound work durably and let a worker send it. For stronger consistency, use a transactional outbox: save the business change and its event record in the same database transaction, then let a separate process dispatch committed events.
That closes a dangerous gap. Without it, Drupal could save a new price and crash before recording the notification. Implementing an outbox requires checking the actual transaction boundaries of your write path; merely adding a queue does not provide the same guarantee.
Plan for repeated delivery attempts. A receiver may accept an event, then lose the connection before the sender receives its acknowledgment. The sender cannot safely assume the event failed.
Keep the event ID unchanged across retries. Consumers should make updates idempotent, meaning that processing the same event again does not repeat its business effect. Persisting the event ID and applying the update need coordinated handling, so a crash between those steps doesn’t lose or duplicate work.
A practical retry policy includes:
- Bounded connection and response timeouts.
- Exponential backoff with jitter to spread retry traffic.
- Respect for rate-limit instructions such as
Retry-After. - A maximum retry age or attempt count, followed by a failure store.
- Different handling for temporary outages and errors that need a payload or configuration fix.
An authentication failure usually needs someone to check credentials. Retrying it rapidly won’t help.
Agree on acknowledgment semantics too. The receiver should return success after it has durably accepted the event, which may happen before it finishes updating an index.
Events can arrive out of order. Use source-defined resource versions to reject older updates, or fetch the latest state when intermediate values don’t matter. Timestamps alone may be insufficient for ordering because clocks can differ and changes can share the same timestamp.
How do signatures protect a webhook?
A signature helps the receiver verify that a request came from a sender holding the shared secret and that the signed content hasn’t changed.
A common approach uses HMAC with a separate secret for each endpoint. Define the exact signing format, including the timestamp, separator, and raw request body bytes. Both sides need the same byte-level rules.
The receiver will:
- Read the raw body without reformatting the JSON.
- Check that the signed timestamp falls within the accepted time window.
- Recompute the signature using the endpoint secret.
- Compare signatures with a timing-safe comparison.
- Check the event ID to handle duplicates safely.
Use a fresh signed timestamp for each retry while retaining the original event ID and occurrence time. This allows legitimate delayed retries without accepting old captured requests indefinitely.
Signatures do not encrypt payloads. Use HTTPS, keep secrets out of payloads and logs, and plan rotation. A key identifier and a short overlap between old and new secrets can help avoid interruptions during a rotation.
Security also depends on where requests go and what they contain. Send only data the destination may receive, particularly for customer-specific prices or unpublished content.
Restrict who can configure outbound URLs. Validate destinations and redirects, and apply network controls to reduce server-side request forgery risk, including access to private networks and cloud metadata endpoints. For inbound requests, set body-size and rate limits so signature verification and queue storage cannot consume unbounded resources.
What changes when an ERP or PIM pushes into Drupal?
The direction reverses, but the reliability principles stay the same.
Field ownership and import rules for inbound catalog data are covered in Connecting Drupal to PIM and ERP as sources of specifications.
An ERP or PIM sends a notification. Drupal verifies the request, checks the envelope, durably records accepted work, and acknowledges it. A worker then validates and maps the update to the correct entity.
Start with field ownership. Suppose the ERP owns stock and lead times while Drupal editors own product descriptions. The import should update the ERP-owned fields rather than replace the entire entity. That protects editorial work and makes conflicts easier to explain.
Before implementation, agree on:
- How external product and location identifiers map to Drupal entities.
- Which system owns each field.
- How the source expresses versions, units, currencies, and languages.
- What happens when a referenced product doesn’t exist.
- Which validation failures need human review.
Handle duplicate events and older source versions before applying changes. Use supported entity APIs for writes so Drupal can run relevant validation, hooks, and cache invalidation behavior. Direct database updates bypass parts of that lifecycle and make consistency harder to maintain.
Watch for feedback loops. An inbound stock update could trigger an outbound entity-change event that another system sends straight back. Track the origin and define which inbound changes may produce new outbound events.
Keep a periodic reconciliation job. Comparing source versions or agreed fields can reveal missed events, mapping errors, and records that drifted during an outage.
Which caches need attention after a data change?
Saving the new price is only part of the job. A cached product page, API response, or retrieval index may still expose the old price.
Trace the whole path.
Within Drupal, use entity APIs and correct cache metadata so dependent output carries the cache tags needed for invalidation. Custom computed output needs particular attention: if a price comes from an external table or service, Drupal may need explicit cache tags and invalidation logic for that dependency.
Cache contexts matter too. If prices differ by customer group, the cached representation needs the appropriate variation and access rules. Fresh data shown to the wrong customer is still a serious problem.
Outside Drupal, treat each layer separately:
- Reverse proxies and CDNs: Configure purges or expiry behavior for the representations they cache.
- API gateways: Check whether they retain responses independently of Drupal.
- Search and retrieval indexes: Update or remove records through their own ingestion process.
- Feeds and generated files: Rebuild affected output on a schedule that meets the freshness target.
Test the order of operations. If Drupal commits an update and immediately sends a compact notification, the consumer’s follow-up fetch might reach a CDN that still holds the previous representation.
Where that risk matters, use a suitably configured authenticated fetch path, compare the fetched resource version with the event version, or send a snapshot. Version checks will let the consumer detect stale reads rather than quietly accept them.
How will the team spot and recover failed updates?
A webhook is useful only if someone can tell when it stops working. Make delivery status visible before the first production outage.
Record the event ID, destination, attempt count, response code, queue age, and delivery latency. Store enough error detail to diagnose problems without logging secrets or unnecessary sensitive payload data.
Measure two different milestones:
- Accepted: The receiving endpoint has durably accepted the notification.
- Applied: The consumer has updated the data that people or assistants actually use.
An HTTP success response may prove only the first. Where consumers can report processing status, use it to measure the delay from source change to usable data.
Alert on growing queue age, repeated destination failures, and exhausted retries. A queue can accumulate delays even when most requests succeed, so failure counts alone won’t show the full picture.
Give exhausted deliveries a dead-letter path: a queue or failure store where the team can inspect an event, fix the cause, and replay it safely. Preserve the original event ID during a replay. Check resource versions so replaying an old snapshot cannot overwrite newer data.
Before launch, test the failures you expect to survive:
| Test | Expected behavior |
|---|---|
| Duplicate delivery | The consumer avoids repeated business effects |
| Timeout after acceptance | A retry does not duplicate the update |
| Consumer outage | Events remain durable and retry within agreed limits |
| Rate limiting | The sender respects the receiver’s retry instructions |
| Out-of-order events | Older data does not overwrite newer data |
| Invalid signature | The receiver rejects the request without applying it |
| Stale cache response | The consumer detects or avoids the older representation |
| Exhausted retries | The team can inspect and replay the failed delivery |
Assign an owner for investigating failures and an owner for authorizing replays. These can be the same team, but the responsibility needs to be clear before an urgent stock update gets stuck.
Common integration pitfalls are described in 5 Problems You May Encounter When Integrating Drupal with Third-Party Software.
Ready to start?
Start with one time-sensitive flow: ERP stock updates, price notifications, or publication changes feeding a retrieval system.
Bring that flow to a conversation with Droptica. Together, we’ll identify the source of truth, acceptable delay, consumer needs, and recovery path. Then we’ll assess whether a Drupal webhooks module, custom integration code, or an integration service fits the job and estimate the implementation around those requirements. Learn more about our Drupal development services.