Webhook vs. API: Choose by Freshness, Authority, and Recovery
An API lets one system ask another for data or request an operation. A webhook reverses who starts the conversation: after a consumer registers a URL, the provider sends a request when a relevant event occurs. The OpenAPI Initiative describes webhooks as out-of-band requests sent to a consumer-chosen URL and acknowledged by that consumer.

That makes “API pulls, webhook pushes” a useful first approximation, but a poor final design rule. Webhooks are usually delivered through HTTP APIs, while APIs can do far more than polling. The business distinction is narrower: an API request is useful when the consumer needs current state or wants to perform an action; a webhook is useful when the provider needs to announce that something happened.
For a martech team, the choice often appears inside a familiar workflow. A prospect changes a form submission, a contact revokes consent, or an opportunity reaches a new stage. A webhook can make the downstream system react promptly. An API can then retrieve the full record, confirm its current state, and repair any gap later. The best design is therefore often a hybrid—not because more components are automatically better, but because notification and authoritative retrieval solve different failures.
The real difference is who initiates the work
Imagine that a CRM contains 500,000 contacts and a downstream audience tool needs to know when consent changes. Polling asks the CRM for changes on a schedule. A webhook asks the CRM to send a notification when the consent event occurs. In both cases, data crosses a system boundary, but the timing, resource cost, and recovery burden land in different places.
| Decision dimension | API request or polling | Webhook delivery | Hybrid pattern |
|---|---|---|---|
| Interaction starts with | Consumer | Provider | Provider notification, then consumer retrieval |
| Best fit | Current-state lookup, mutation, backfill | Prompt event notification | Prompt reaction plus authoritative state |
| Freshness depends on | Request or polling cadence | Provider event and delivery latency | Webhook latency for detection; API latency for lookup |
| Main capacity pressure | Request volume, pagination, concurrency, rate limits | Inbound endpoint, queue, bursts, retries | Both, but each can be sized for a narrower job |
| Common recovery unit | Cursor, page, object ID, or time window | Provider redelivery or stored event | Redelivery plus bounded API reconciliation |
| Main blind spot | Changes between polls remain unseen until the next run | A lost or unprocessed event can leave no current-state view | More moving parts and two provider contracts to operate |
This comparison rules out a common shortcut: freshness alone does not decide the mechanism. A webhook may arrive quickly but carry a thin payload, stale snapshot, or event that reaches the receiver after a newer event. Polling may be slower by design yet give the consumer a repeatable way to retrieve a complete time range. The question is not simply “Which is faster?” It is “Which failure can we detect and repair?”
When webhook-first is the right default
Lead with a webhook when the provider emits the exact event you need, the useful response window is shorter than a practical polling interval, and your receiver can accept traffic at the provider’s pace. A lead-routing rule that must run soon after a form submission is a natural candidate. So is a consent change whose downstream suppression should not wait for an overnight batch.
The endpoint still has to do more than receive JSON. It needs the provider’s documented method for authenticating the sender, a way to distinguish supported event types and versions, durable acceptance before acknowledgement, and repeat-safe downstream processing. GitHub, for example, advises consumers to subscribe only to needed events, validate deliveries with a webhook secret, inspect the event and action, and use its delivery identifier; those are GitHub-specific practices, not universal webhook guarantees.
A webhook is a weak choice when the provider does not expose the event, retains failed deliveries for too short a period, or gives no stable identity that supports duplicate-safe handling. It is also weak when nobody can operate the public receiver, queue, alerts, and replay path. Low latency does not compensate for an invisible failure.
When API-first is the right default
Lead with API retrieval when the consumer needs current state on demand, the source changes slowly, or a bounded scan is easier to recover than individual event deliveries. A daily campaign-membership export, for example, may gain little from instant notifications. A cursor-based request that resumes from the last completed boundary can be simpler to inspect and rerun.
Polling also gives the consumer control over cadence, page size, overlap, and backfill. That control has a cost. Calls consume a provider-defined budget, and a loop that repeatedly scans unchanged records can waste most of it. GitHub’s REST API illustrates why rate limits must be treated as part of the contract: it applies both primary and secondary limits and returns headers that expose the primary request budget and reset time. Its documented response to limit errors depends on fields such as retry-after, x-ratelimit-remaining, and x-ratelimit-reset.
There is no portable polling interval. Start from the maximum delay the business can tolerate, then check whether the resulting request volume fits the provider’s pagination and rate-limit rules. Persist the last fully processed cursor or time boundary. If records can arrive late or timestamps can shift, reread a small overlapping window and deduplicate the overlap. The last attempted time is not the same as the last complete time.
Reliability changes the decision after the first successful request
A demonstration usually proves that one webhook can arrive or one API request can return data. Production reliability begins with the second attempt: a retry after a timeout, a duplicate event, a delayed page, or two messages that reach the consumer in the wrong order.
Webhook delivery is not universally exactly once. Stripe’s current documentation says that an endpoint can receive the same event more than once and that event order is not guaranteed; it recommends logging processed event IDs and, in some duplicate cases, pairing the object ID with the event type. Stripe also documents automatic retries for its own service. The schedule and retention period belong to Stripe’s contract. They cannot be copied into a design for another provider.
This matters because most webhook deliveries use POST. Under RFC 9110’s definition of idempotency, repeating an idempotent method has the same intended server effect as sending it once; POST is not among the methods the RFC defines as inherently idempotent. A receiver must protect the business effect itself. Recording a delivery ID may stop the same delivery from running twice, while a separate business key—such as contact, consent version, and destination—can prevent two different events from applying the same transition twice.
Order needs similar care. If an “opportunity won” event arrives before an earlier “opportunity updated” event, processing in arrival order could move the record backward. Compare source versions or timestamps where the provider defines them, retrieve current state when order matters, and reject a transition that is older than the state already applied. Do not manufacture ordering from fields whose semantics the provider has not documented.
Acknowledgement deserves its own boundary. Stripe tells receivers to return a successful 2xx response before complex work that might time out. GitHub’s documented rule is more specific: a receiver should respond with a 2xx within ten seconds, after which GitHub considers the delivery failed. A fast response should mean that a verified event has been durably accepted, not that the entire CRM update, audience sync, or email suppression finished.
Never acknowledge first and rely on in-memory work when losing the event would create an unrecoverable business error.
That separates three states that dashboards often blur: rejected input never entered the workflow; accepted input was verified and durably stored; completed input produced the intended downstream effect. An endpoint can be healthy at the HTTP layer while accepted events are accumulating in a failed queue. Monitor the business transition, not only the response code.
A hybrid gives notification and state separate jobs
Use a hybrid when the event needs a prompt reaction but the API remains the reliable source for full or current state. The webhook wakes the workflow. The API answers what is true now. A scheduled reconciliation catches what neither path handled correctly the first time.
The distinction is visible in Stripe’s own event models: its webhook documentation notes that a snapshot event can be followed by retrieval of the latest resource, while a thin event handler fetches the related object. That is a provider-specific example of a broader design judgment. Treat the event as proof that something may require attention unless the provider contract explicitly makes its payload authoritative for the decision at hand.
A workable hybrid can be specified as one end-to-end path:
- Name the business transition. Define the source event, the authoritative object, the downstream effect, the maximum useful delay, and the consequence of loss or duplication. “Sync the CRM” is too broad; “remove a contact from paid audiences after consent becomes revoked” is testable.
- Verify the incoming request. Apply the provider’s signature or secret procedure to the unmodified material it requires, then validate the event type, account scope, and payload version. Transport security and sender verification are separate checks.
- Persist before acknowledging. Store the provider’s delivery or event identity with the raw or normalized payload and a processing state, or place it on a durable queue. Return the provider-defined success response only after that durable boundary has been crossed.
- Deduplicate at two levels. Reject a repeated delivery identity, then protect the downstream business transition against semantically duplicate events. Keep both rules because one provider event ID does not necessarily represent one business effect.
- Retrieve current state when the decision requires it. Ask the API for fields omitted from the event, a newer object version, or permissions that may have changed. If the webhook already carries sufficient authoritative state, avoid the extra call.
- Apply and record the effect. Make the downstream operation safe to repeat, and retain enough status to distinguish pending work, a retryable failure, and a terminal rejection.
- Reconcile a bounded range. On a schedule justified by business consequence, query from the last complete cursor or time boundary, include any necessary overlap, and send missed records through the same idempotency rules.
This design does cost more to operate than a single request path. It needs an inbound receiver, API credentials, storage, monitoring, and a reconciliation schedule. Use it when those components close a material loss or staleness gap—not as a default badge of architectural maturity.
Choose the repair path before the trigger
For a consequential martech transition, begin with the failure you cannot afford to leave hidden. If a late update is acceptable and bounded retrieval is easy to rerun, API polling may be enough. If prompt awareness matters and the provider’s delivery contract is operable, start with a webhook. When prompt notification and trustworthy current state are both necessary, pair them and make reconciliation part of the design from the first release.
The decisive question is concrete: after a timeout, duplicate, or missed interval, can the team identify the affected business objects and safely produce the right final state? Choose the mechanism that gives you a credible yes.
Frequently asked questions
Can a webhook replace an API?
A webhook cannot replace an API when the consumer must search historical records, request a backfill, change an object, or retrieve fields absent from the event. Some providers send complete snapshots, while others send only an identifier or a small notification. Check the payload contract before treating webhook delivery as a self-contained data interface.
How do you recover webhooks missed during an outage?
Use the provider’s delivery log or redelivery feature if one exists, but do not assume it retains the full outage window. Record the outage boundaries, replay available deliveries, and use an API query over the same bounded period to locate missing state. Send replayed and retrieved records through the normal deduplication path so recovery does not create a second incident.
Does HTTPS make a webhook secure?
HTTPS encrypts the connection and authenticates the server to the sender through its certificate; it does not by itself prove to your application that the request came from the expected webhook provider. Use the provider’s documented signature or shared-secret validation, keep credentials out of the callback URL, and enforce any timestamp or replay checks that the provider specifies.
How often should an API be polled?
Set the cadence from the maximum tolerable detection delay, then test that request count against the provider’s actual page size, change volume, and rate-limit contract. A five-minute cadence creates 288 scheduled runs per day before pagination or retries; that arithmetic is illustrative, not a recommended interval. Slow the loop, use incremental cursors, or switch to event notification if the required cadence cannot fit the available request budget.