In SharePoint on-premises, event receivers (and later Remote Event Receivers in the Add-in model) were the default way to react to list and library changes: item added, item updated, item deleted, and so on. That model gave you server-side execution close to the data—powerful, but also tightly coupled to the farm and often painful to upgrade.
Replacing SharePoint On-Prem Event Receivers with SharePoint Webhooks + Azure Functions (Enterprise Blueprint)
In SharePoint on-premises, event receivers (and later Remote Event Receivers in the Add-in model) were the default way to react to list and library changes: item added, item updated, item deleted, and so on. That model gave you server-side execution close to the data—powerful, but also tightly coupled to the farm and often painful to upgrade.
In SharePoint Online (Microsoft 365), Microsoft intentionally steers engineering teams away from server-side extensibility and toward API-first + remote compute patterns. The modern replacement is a combination of:
- SharePoint Webhooks to notify your solution when content changes
- Azure Functions to host the listener and run business logic
- Optional queues / durable orchestration for reliability and scale
Microsoft Learn provides a direct reference pattern for hosting SharePoint webhooks in Azure Functions. (Microsoft Learn)
This article provides an enterprise-ready blueprint: not just “how to do it,” but how to do it reliably, securely, and deployably via DevOps.
1) Why webhooks are the “new event receiver” in M365
What webhooks give you
SharePoint webhooks allow you to subscribe to changes in a target list and have SharePoint send notifications to your endpoint when changes happen. (Microsoft Learn)
What webhooks do not give you (important)
Webhooks are notifications, not the data itself. Your service typically receives “something changed” and then queries SharePoint to fetch details and process changes.
This is the key mindset shift from on-prem event receivers:
- On-prem: logic runs “inside” SharePoint during the transaction pipeline.
- M365: logic runs externally and pulls what it needs after notification.
2) Architecture: the enterprise pattern that scales
A production-grade design looks like this:
- SharePoint list emits change notification → sends webhook call to your endpoint
- Azure Function (HTTP Trigger) receives notification
- Function does minimal work and pushes the “work item” to a queue (recommended for reliability)
- A second Function (Queue Trigger) processes the work item:
- queries the changed items
- applies business logic
- writes back to SharePoint / calls other APIs
Microsoft Learn shows Azure Functions as an easy hosting model for SharePoint webhooks. (Microsoft Learn)
Microsoft also documents a PnP reference implementation using Azure components (queues, SQL, background processing) to handle webhook notifications in an enterprise-ready way. (Microsoft Learn)
Why the queue step matters: Webhooks can arrive in bursts, can repeat, and your function must respond quickly. Offloading work to async processing is what makes the solution resilient.
3) The three “must-haves” that break most webhook solutions
3.1 Subscription validation
When you create a subscription, SharePoint validates that your notification endpoint is real. Your service must echo back the validation token in time, otherwise the subscription won’t be created. (Microsoft Learn)
This is the most common “it doesn’t work” moment when people first move from event receivers to webhooks.
3.2 Subscription renewal
Webhook subscriptions have a lifetime and must be renewed. Microsoft’s modernization guidance explicitly calls out renewal as a required step in the webhook model. (Microsoft Learn)
3.3 “At least once” delivery and duplicates
Webhook notifications should be treated as at-least-once delivery:
- you can receive duplicates
- you can receive bursts
- you might need idempotency
That means your processing must be safe to run more than once (idempotent design).
4) Hosting the listener in Azure Functions: what Microsoft recommends
Microsoft Learn provides two practical tracks:
Track A — Azure Portal / manual setup
“Using Azure Functions with SharePoint webhooks” shows how to host webhook code and benefit from serverless hosting/scaling. (Microsoft Learn)
Track B — Automated deployment using Azure Developer CLI (azd)
Microsoft also provides an approach using azd templates to deploy the function app and related resources. (Microsoft Learn)
If your organization is serious about DevOps and repeatability, Track B is usually closer to how you want to run this in production.
5) Operational design: reliability patterns you should adopt
5.1 Queue-based processing (recommended)
Use a queue so your HTTP function:
- validates quickly
- acknowledges quickly
- doesn’t time out under load
- doesn’t drop work
This is aligned with the enterprise reference pattern described by Microsoft’s PnP webhook implementation guidance (queues + background processing). (Microsoft Learn)
5.2 Idempotency
Idempotency means: if you process the same notification multiple times, the outcome is the same.
Common tactics:
- Store “processed change tokens” (or item version identifiers) in a store
- Use a deterministic “operation ID” and check before applying changes
- Design updates as “set to value” instead of “increment”
5.3 Throttling and backoff
SharePoint Online can throttle aggressive workloads. Your queue worker should:
- batch requests
- use retry policies with exponential backoff
- avoid “chatty” patterns
6) Subscription renewal using Timer Trigger Functions
You will almost always want a scheduled job to renew subscriptions.
Azure Functions provides Timer Triggers to run a function on a schedule. (Microsoft Learn)
A clean pattern is:
- Store active subscriptions (list ID, expiration, notification URL, secret metadata) in a store
- Timer trigger runs every X hours
- Renew subscriptions approaching expiration
- Alert if renewal fails
Timer triggers are explicitly documented as the mechanism to run scheduled jobs in Azure Functions. (Microsoft Learn)
7) DevOps: treat your webhook solution like a product, not a script
A modern M365 solution should be:
- source-controlled
- built in CI
- deployed in CD
- monitored and audited
A practical CI/CD checklist
CI
- build & test function app
- lint / static analysis
- package artifact
CD
- deploy function app to Dev/Test/Prod
- configure app settings via pipeline variables/key vault references
- run smoke tests (validate endpoint responds to validation token correctly)
- deploy subscription renewal schedule
- (optional) deploy subscription registration scripts
Microsoft Learn also covers Azure Functions concepts around triggers and bindings, reinforcing how the platform expects these workloads to be built and deployed. (Microsoft Learn)
8) Security baseline: modern identity and secrets management
While this article is not a full security deep dive, the enterprise minimum should include:
- Managed Identity where possible (for Azure resources)
- Secret storage (Key Vault) for credentials if required
- Least privilege when accessing SharePoint
- Avoid embedding secrets in code or config files
Even if your first version uses a simpler auth flow, plan to mature the security posture early—especially if your function can modify content or permissions.
9) Where PnP fits in this webhook-driven world
PnP isn’t just “provisioning templates.” It’s also a practical toolkit mindset: repeatable patterns and community-backed guidance for SharePoint engineering.
The PnP provisioning framework is positioned as a template-based, code-oriented provisioning platform that supports SharePoint Online and even on-prem site collections. (Microsoft Learn)
In real enterprise projects, PnP complements webhooks by ensuring:
- lists/fields/content types exist consistently
- target sites are provisioned the same way across environments
- you don’t build “automation that assumes manual SharePoint setup”
10) Recommended adoption path (migration strategy)
A safe modernization sequence:
- Identify legacy event receivers and categorize them:
- validation rules
- sync/integration
- metadata enforcement
- notifications
- Pick one workflow and rebuild it with:
- SharePoint webhook → Azure Function HTTP endpoint
- queue-based worker
- timer-based subscription renewal
- Harden:
- idempotency
- retry/backoff
- monitoring/alerts
- Standardize:
- IaC /
azdtemplates or your pipeline templates - consistent environment configuration
- IaC /
- Scale out to other lists and processes
Microsoft’s modernization guidance explicitly frames the webhook model as requiring a listener, subscription management, validation, and renewal. (Microsoft Learn)
Summary tables
A) On-prem Event Receivers → M365 Webhooks
| Legacy capability | On-prem implementation | Microsoft 365 replacement pattern |
|---|---|---|
| React to list changes | Event Receiver in farm | SharePoint Webhook → Azure Function listener (Microsoft Learn) |
| Scheduled renewals / nightly jobs | Timer Jobs | Azure Functions Timer Trigger (Microsoft Learn) |
| “Enterprise async handling” | Custom queues/jobs | Queue + worker functions (PnP ref pattern) (Microsoft Learn) |
B) The 5 production “non-negotiables”
| Requirement | Why it matters | Where documented |
|---|---|---|
| Validation token response | Subscription fails without it | SharePoint webhooks overview (Microsoft Learn) |
| Subscription renewal | Subscriptions expire | Modernization guidance (webhooks) (Microsoft Learn) |
| Idempotency | Duplicates happen | Enterprise best practice (webhooks model) |
| Async processing | Avoid timeouts and bursts | PnP reference implementation (Microsoft Learn) |
| Timer-based operations | Clean scheduled automation | Timer trigger docs (Microsoft Learn) |
