Best Way to Receive Updates from APIs Without Webhooks (Without Building Polling Systems)
·
For developers integrating third-party APIs that offer no webhooks, the best way to receive updates is to move change detection out of your application and receive changes as events, instead of building a polling system. On Unified.to, a virtual webhook checks the integration's API on an interval you set, as often as every minute on paid plans, and delivers what changed to your webhook URL in the same format as a native webhook, so your application stays event-driven whether or not the underlying API has webhooks. Incremental polling with an updated_at cursor also works, but at scale it becomes a system your team builds and operates: schedulers, cursor storage, pagination, retries, rate-limit handling and reconciliation.
What are the three ways to receive updates from an API?
The three ways to receive updates from an API are: your application polls the API, the API sends webhooks (see webhook vs API for the basics), or an integration layer detects changes and delivers them as events. Most APIs support the first; many support the second for some objects; the third depends on the platform you build on. For a fuller comparison of the first two, see Polling vs Webhooks: When to Use One Over the Other.
| Approach | How it works | Tradeoffs | What you maintain |
|---|---|---|---|
| Polling | Your app repeatedly calls the API to check for updates | Universal; latency equals the interval; most requests find nothing | Scheduler, cursors, pagination, retries, backoff, reconciliation |
| Native webhooks | The API sends an event when a record changes | Fast; not available on many APIs, or only for some objects | Endpoint, signature verification, idempotency |
| Event delivery layer (virtual webhooks) | The integration layer checks the API, detects changes, delivers events | Same interface as native; latency equals the configured interval | Endpoint, signature verification, idempotency |
What is incremental polling, and why is it the default?
Incremental polling is a scheduled read that asks the API for records changed since a stored cursor, usually an updated_at timestamp or a change token, followed by an idempotent upsert. It's the default because it needs nothing from the API beyond a list endpoint with a since-filter, which nearly every API has.
To make it reliable across many customers, a team ends up building schedulers across tenants, cursor storage per resource, pagination handling, retry and backoff logic, rate-limit coordination, and reconciliation jobs for anything missed. At scale, most of those scheduled reads return nothing while still consuming the API's quota and your infrastructure.
What are the other request-based options, and where do they stop?
Four variations reduce the cost of polling without removing it: conditional requests, delta queries, long polling and snapshot diffing. Each still requires your application to ask, and each depends on the API supporting it.
Conditional requests (ETag, If-Modified-Since) let the server answer 304 Not Modified with no body when nothing changed, as defined in RFC 9110. They cut payload size, but the request still counts, they don't tell you which records changed, and support is inconsistent across APIs.
Delta queries return only what changed since a token you pass back. This is the cleanest pull model where it exists. It's provider-specific in shape, tokens expire and reset in ways you have to handle, and few SaaS APIs offer one.
Long polling holds a request open until something changes. It needs the API to support it, adds connection management, and doesn't generalize across integrations.
Snapshot diffing fetches the whole dataset, compares it with the previous state, and infers changes. It's the last resort where no cursor exists, and it's expensive and slow on large datasets. Some integration platforms run this model on your behalf: as of 8 October 2026, Apideck's help centre describes its virtual webhooks as retrieving all items per resource on each cycle, "typically every 24 hours," with a one to two minute pause between pages.
Why does polling turn into infrastructure?
Polling turns into infrastructure because the guidance to "use incremental polling" stops where the work starts: scheduling across tenants and integrations, tracking cursors, handling retries and failures, managing rate limits, and reconciling missed updates are each a component, and together they're a system. Teams that make polling reliable end up with API reads, change detection, internal event generation and downstream consumers. In other words, they convert request-driven APIs into an event-driven system, which is the same pattern integration platforms and data pipelines use.
How can I detect changes in third-party APIs without building polling jobs?
You can detect changes in third-party APIs without building polling jobs by moving change detection into the integration layer, which reads from source APIs, detects changes using timestamps or cursors, and delivers those changes as events, so your application only receives. Unified.to's virtual webhooks do this on supported integrations and objects. The checks against the API still happen; the scheduled reads, cursors and retry logic just don't live in your codebase, and they're written once rather than once per integration. For how a virtual webhook detects changes compared with a polling job, see What Are Virtual Webhooks?
How do I get webhook-style events from APIs that don't support webhooks?
To get webhook-style events from APIs that don't support webhooks, create a Unified.to virtual webhook: Unified.to detects changes and delivers events to your webhook URL on supported integrations and objects, in the same signed format as native webhooks, with the changed records in the event where supported. Unified.to provides one webhook interface across integrations, using the integration's native webhooks where they exist and virtual webhooks where they don't, so your application receives the same signed POST in either case. As of September 2026:
- When native webhooks exist, Unified.to registers the subscription with the integration and forwards events as they arrive. Events carry the changed records where supported, so a follow-up fetch is usually not needed.
- When they don't, a virtual webhook checks the integration on your interval, as often as every 1 minute on paid plans and every 60 minutes on the free trial, detects changes using timestamps and cursors, and delivers them. Virtual webhooks are available on supported integrations and objects. No customer records are stored at rest between checks; a failed delivery is retried by re-reading the same page from the integration.
- The payload is the same for both: an array of records in the API's format, a
typemarker, your connection'sexternal_xref, and an HMAC-SHA256 signature. Events arecreated,updatedanddeleted. Nativedeletedevents come through where the integration sends them; virtualdeletedevents are reliable only on BambooHR, Dropbox, Google Drive, Gmail, JobAdder, OneDrive, SharePoint, RingCentral, Egnyte and Box. - Historical data comes through the same subscription. Create the webhook with
include_all=trueand, wherever initial sync is supported, existing records are delivered in pages, taggedINITIAL-PARTIALthenINITIAL-COMPLETE, before ongoing events begin. - One subscription model covers chat, file storage and databases. A webhook on a messaging object (such as messages) or a file storage object (such as files) delivers records in one normalized model per category, so the same handler works for Google Drive, Dropbox or OneDrive. To land changes in a database instead of an endpoint, Database Sync is a webhook with a database destination (MongoDB, MySQL, Postgres, MSSQL, MariaDB, Supabase or Snowflake), available on Grow, Pro and Scale and billed like webhooks.
- Rate limits, retries and backoff are handled for you. Checks that hit the integration's rate limit back off and honour its retry-after guidance. Failed deliveries to your endpoint on native webhooks are retried three times immediately, then the webhook is marked unhealthy. Virtual webhooks retry up to three times, one second apart, then back off progressively for up to about two weeks, re-reading the page from the integration on each retry; the cursor advances only after a successful delivery, and if retries are exhausted the webhook is marked unhealthy and scheduling stops.
- Health is yours to watch. Every webhook has an
is_healthyfield; an unhealthy one stops and doesn't resume until you fix the cause and recreate it. Subscribe toWEBHOOK_UNHEALTHYon the notifications webhook so you find out; How to troubleshoot unhealthy webhooks covers diagnosis and recovery. - Billing follows changes, not checks. Checks that find nothing aren't billed; you're billed per page of changes successfully delivered.
Which type an integration supports, per object, is on its Feature Support tab in the dashboard. Setup is covered in How to create and configure webhooks, and the difference between this model and platforms that store your data and notify you after a sync is in Which Unified API Platforms Support Virtual Webhooks vs Sync-Based Notifications.
Why does where the polling lives matter?
Where polling lives matters because it decides who builds and maintains it: your team, in your codebase, once per integration, or the integration layer, written once, with your application receiving events. Polling is an implementation detail of reading an API that can't send events, so the useful question is why polling infrastructure sits inside your application at all.
What's the best way to receive updates from APIs that don't provide webhooks?
The best way to receive updates from APIs that don't provide webhooks is to receive changes as events instead of building polling yourself: Unified.to's virtual webhooks detect changes and deliver events on supported integrations and objects, the events carry the changed records where supported, and checks that find nothing aren't billed. Polling works, but at scale it becomes a system: change detection, event routing, retry and rate-limit handling. Unified.to centralizes that system by forwarding native webhooks where they exist and detecting changes and delivering events where they don't, so your application stays event-driven without building or maintaining polling infrastructure.
Frequently asked questions
Do virtual webhooks eliminate requests to the integration's API? No. The checks still call the integration's API and count against its rate limits; Unified.to backs off automatically when it's rate-limited. What's eliminated is the polling code in your application and any charge for checks that find nothing.
What if the API has no updated_at field?
Change detection depends on what the integration's API provides. Where an object has no usable timestamp or cursor, virtual webhooks may not be available for it. Check the object on the integration's Feature Support tab before building on it.
How is this different from a platform that syncs my customers' data and notifies me? A sync-based platform stores a copy of the data on its schedule and sends a notification when the sync completes, which you follow with an API call to fetch what changed. A virtual webhook reads from the source, stores no customer records at rest between checks, and delivers the changed records in the event itself where supported.
→ Start your 30-day free trial
Written by Mallory Greene.
About the author: Mallory Greene is Head of Marketing at Unified.to. She writes about integration infrastructure, unified APIs, and MCP for technical teams. Based in Toronto.