
PrismHR change detection: subscription events vs webhooks
Summarise the blog with AI

Key takeaways
- PrismHR's Core and Services API detects change through poll-based SubscriptionService events. No public Core push-webhook method appears in its documentation.
- Webhooks do exist in the PrismHR family for Hiring and ATS, which is a different surface and not a substitute for Core change detection.
- Granting
getNewEventsmeans adding the Allowed MethodSubscriptionService.getEvents, which grants both together. PrismHR's own documentation describes this inconsistently. - A subscription event is a signal, not the changed record, so a reliable sync always adds a resolve-then-fetch step after the poll.
- Polling reliably needs a checkpoint and an idempotent apply step, because at-least-once delivery means the same event can legitimately arrive twice.
PrismHR change detection
Search PrismHR's API documentation for how to detect a change and you will not find a webhook registration endpoint. That is not a documentation gap. PrismHR's Core and Services API does not appear to expose one.
Build your sync assuming push notifications and you will stand up a callback endpoint that never receives a call, then rebuild your change-detection layer around polling anyway, weeks after the deadline you set expecting a webhook to work.
The two models cost different things. A webhook costs you a public, always-available endpoint. A poll loop costs you a checkpoint, a schedule, and a plan for the event that arrives twice.
This guide covers what PrismHR actually gives you, how the pull model differs from the push model you probably assumed, the exact method set and the permission that trips up most integrations, and the pattern that turns a stream of events into a sync you can trust.
What you are really deciding: push or pull
Most APIs a backend engineer touches now push. Stripe fires a webhook on a charge. GitHub fires one on a commit. So "how do I detect changes in PrismHR" gets typed as "how do I set up PrismHR webhooks," when the question underneath is simpler: does the responsibility for noticing a change sit with PrismHR calling you, or with your integration calling PrismHR.
A second mismatch waits once the first resolves, and it shapes everything after it. A subscription event is not the changed record. A garnishment event hands you a client ID and a garnishment ID, and leaves you to call EmployeeService.getGarnishmentEmployee to find out whose record actually changed. The event tells you something happened. It does not tell you what.
That distinction is the piece most integrations get wrong on the first attempt, and it is why the sync pattern later in this guide has a fetch step a webhook-shaped mental model would never think to add.
What PrismHR offers for change detection
PrismHR's Core and Services API detects change through SubscriptionService. You call createSubscription to define what you want to watch, and retrieve what changed with getEvents or getNewEvents, gated by Web Service User access.
No public Core push-webhook method appears in PrismHR's documentation. That is a statement about what is publicly documented, not a claim that no such thing could exist for your account. Webhooks are documented for PrismHR Hiring and ATS, and a given tenant or module may expose something not covered here. Confirm against your own tenant before you build around either assumption.
PrismHR's API surface also moves across versions in ways this guide cannot track for you. Treat the method names below as accurate at time of writing and verify against your tenant's live documentation before you ship. For the credential that gates all of this, see our guide to provisioning a PrismHR Web Service User.
Subscription events and webhooks, compared
Once you know PrismHR's Core mechanism is pull, the comparison that matters is what pull costs you against what push would have cost instead. Push looks free until you have to run it.
Pull puts you in control of retry and backoff, at the cost of managing a schedule and a checkpoint yourself. Push would hand you near-real-time delivery, at the cost of an endpoint that has to be reachable every time PrismHR decides to call it. PrismHR's Core API has already made this choice for you. The rest of this guide is about building well inside it.
The SubscriptionService method set, and the permission you will get wrong
The method set breaks into six calls, used in roughly this order:
createSubscriptioncreates a new event subscription, scoped by filters you defineappendFilteradds filters to a subscription that already existsgetSubscriptionretrieves a single subscription by IDgetAllSubscriptionsretrieves multiple subscriptions at oncegetEventsandgetNewEventsretrieve the events queued against a subscriptioncancelSubscriptionremoves a subscription you no longer need
Here is the part that catches almost every integration on the first attempt. getNewEvents is not its own grantable permission. To give your Web Service User access to it, you add the Allowed Method SubscriptionService.getEvents, which grants both together.
PrismHR's own reference does not agree with itself here. Two of its sources describe the relationship between the two permissions differently, so treat this as documented behaviour to verify in your own tenant rather than a settled fact to build against blind.
Building a reliable sync: resolve, checkpoint, dedup
Knowing the method set gets you a working call. It does not get you a sync you can trust at 3am when a job restarts mid-run. That takes six decisions, in this order:
- Create a scoped subscription. Use
createSubscriptionandappendFilterto watch only the entities and event types your product needs. - Poll on a schedule. Call
getNewEventsat an interval your PrismHR tenant and your own latency requirements can both tolerate. - Resolve each event to a record. The event is a signal, so for a garnishment event, call
EmployeeService.getGarnishmentEmployeeto identify whose record changed before you do anything else. - Fetch the current record. Pull the entity itself through the relevant API rather than trusting anything in the event body as your source of truth.
- Checkpoint your position. Persist the last event ID or timestamp you processed successfully, so a restart resumes from there instead of reprocessing from zero or silently skipping ahead.
- Make reprocessing safe. A poll loop delivers at least once, so the same event can arrive twice after a retry or a restart. Applying it a second time has to leave the record exactly where the first application left it, which is the definition of an idempotent operation under RFC 9110. If you also write back to PrismHR or a downstream system, a request-scoped dedup token, the mechanism behind the IETF's proposed
Idempotency-Keyheader, gives the receiving side a way to recognise a retried write and discard it.
That sequence is the whole job: a subscription, a poll, a resolve, a fetch, a checkpoint, and a dedup rule. Own it correctly and PrismHR's poll-based model is entirely workable. Own it carelessly and the gap between "the event fired" and "the record is actually correct" is where support tickets come from.
When operating the poll loop is not the work you want
Everything above is engineering work you own indefinitely: the schedule, the checkpoint store, the dedup logic, and the on-call rotation for when the poll loop silently stalls.
The alternative is a layer that operates that machinery for you. Bindbee connects to 67+ HRIS, payroll, ATS, and benefits systems through one API, PrismHR among them, and each connector authenticates through the system's own mechanism with no screen scraping.
What that changes on the notification side is worth stating precisely, because it is easy to overclaim. PrismHR does not gain native push webhooks. Bindbee runs a scheduled sync, every 24 hours by default and configurable, and separately delivers webhook notifications when a sync starts, finishes, or fails, and when synced records change. Your systems receive a push instead of running the loop, and the underlying refresh is still the sync interval rather than instant upstream detection.
On PrismHR specifically, Bindbee's connector normalises employee and company records into unified models shared with the other 67+ systems. Across the full connector set, Bindbee normalises into 40+ unified data models covering HRIS, payroll, ATS, and LMS.
Since PrismHR data typically includes protected health information, handling matters as much as mechanism. Bindbee is SOC 2 Type II, ISO 27001, HIPAA, and GDPR compliant, and a standard BAA template is available.
The honest tradeoff: building the poll loop yourself gives you full control over scheduling, retry behaviour, and exactly which fields trigger a notification. A managed layer trades some of that control for not having to operate it. If your team would rather build the product than the sync infrastructure underneath it, that is the trade on offer.
Healthee replaced 15 custom integrations with Bindbee. Newfront cut client onboarding from 8 to 12 weeks down to 48 hours.
We build the integrations. You build the product.
FAQ
Does PrismHR have webhooks?
Webhooks are documented for PrismHR Hiring and ATS. PrismHR's Core and Services API detects change through poll-based SubscriptionService events, and no public Core push-webhook method appears in its documentation. Confirm against your own tenant or module before assuming either way.
How do I grant access to getNewEvents?
Add the Allowed Method SubscriptionService.getEvents to your Web Service User, which grants both getEvents and getNewEvents together. PrismHR's documentation describes this relationship inconsistently across sources, so verify the grant works in your own tenant.
Is a subscription event the full changed record?
No. Treat the event as a signal that something changed, then fetch the current record through the relevant entity API. A garnishment event carries a client ID and a garnishment ID, which you resolve through EmployeeService.getGarnishmentEmployee.
How often should I poll PrismHR?
At the slowest interval your product's latency requirement allows, since every poll consumes a session and API capacity. Pair the interval with a checkpoint so a missed run catches up rather than skips.




.jpg)
