Why Must a Zocdoc No-Show Update Be Sent Within Two Days?

A Zocdoc appointment can be updated to no_show only after its start time is in the past and while that start is no more than two days old. The Scheduling API documents this rule for PUT /v1/appointments/update-status. Once a record is outside that window, continuing the same request indefinitely is not a supported recovery strategy.

The practical fix is to process post-appointment outcomes promptly, surface stale records for review, and keep local reporting separate from the Zocdoc update result. Do not rewrite “two days” as a different unit or promise a particular error response that the cited guide does not document.

What does the update-status endpoint permit?

Zocdoc’s Appointment Actions guide describes PUT /v1/appointments/update-status as the endpoint for updating a booked appointment after its scheduled time. The documented post-appointment statuses are arrived and no_show.

The glossary defines no_show as a patient who did not appear for a confirmed appointment. That definition matters. A cancellation, reschedule, unconfirmed request, integration failure, or staff uncertainty should not be translated into a no-show merely because the original start time passed.

Use the appointment’s actual state and the source contract. The guide to which Zocdoc cancellation and reschedule changes trigger webhooks covers different lifecycle actions. A webhook about a changed booking is not evidence that a completed appointment should be marked no_show.

Keep the outbound request narrow. The status update needs the identifiers and status required by the API. Operational logs can record a synthetic appointment reference, attempted status, attempt time, response class, and final workflow state. They do not need a name, phone number, visit reason, insurance value, or clinical note.

Why does the no-show update have a two-day window?

The official Appointment Actions guide states the boundary: for a no_show update, the appointment start must be in the past but no more than two days old. This defines when the API action is permitted. The source does not explain a broader policy rationale, so an integration should not invent one.

Treat “two days” as the wording of the contract. Do not silently convert it into “48 hours,” end-of-day logic, clinic-local calendar days, or another threshold unless Zocdoc provides that interpretation for the integration. If an edge case matters, test it in the supported environment or ask Zocdoc for clarification.

The time restriction means status collection cannot be an unbounded background task. A queue that waits through repeated outages may eventually contain an appointment that is no longer eligible for the no-show call. Retrying the same payload forever will not make the appointment recent again.

Operational inference: calculate urgency from the scheduled start and current eligibility, while allowing room for transport failures and human review. Zocdoc documents the boundary, but it does not prescribe the clinic’s queue interval or escalation schedule.

How should arrived and no_show remain distinct?

Both values describe an outcome after the appointment time, but they are not interchangeable. arrived represents attendance; no_show represents the absence defined in the glossary. A delayed front-desk update does not make every unresolved appointment a no-show.

Build the decision from an authoritative operational event. That may be a completed check-in, a staff-reviewed disposition, or another clinic-approved signal. The integration should not infer absence from a missing webhook, a blank field, or a temporary inability to reach the source system.

Likewise, do not use no_show to repair a cancellation or reschedule mismatch. Preserve the appointment lifecycle and investigate its actual transition. The article on preserving original booking source after a reschedule explains why changing operational state should not erase acquisition lineage.

A stale local record can remain classified for internal review even if the vendor update is no longer eligible. That local state must be labeled honestly. “Observed by clinic, not confirmed updated in Zocdoc” is different from “Zocdoc status updated.”

What queue design respects the window?

Store post-appointment candidates with their scheduled start, current local outcome, vendor appointment identifier, and next action. When the approved source confirms a no-show, attempt the update while the documented time condition still holds.

Separate temporary delivery failure from contract ineligibility. A network interruption or retryable server response may justify another bounded attempt. A record that has aged outside the allowed window needs a terminal workflow state and human-visible explanation, not another automatic request.

  1. Confirm the appointment start is in the past.
  2. Confirm the clinic’s source supports the no_show outcome.
  3. Check that the start is no more than two days old.
  4. Send the status update with the required vendor identifier.
  5. Record success, retryable uncertainty, or stale review as different states.
  6. Stop automatic retries when the request is outside its supported window.

Do not assume webhook delivery will recover the task. The analysis of Zocdoc appointment webhooks after an HTTP 500 shows why inbound delivery behavior and outbound status updates need separate reliability controls.

What should happen after the window has passed?

Surface the item as stale. Preserve the clinic’s evidence and the last vendor response, but do not label the external update successful. The cited guides establish the eligibility boundary; they do not promise a specific error code or a late-update exception.

Human review can determine whether the local scheduling record, reporting layer, or support process needs correction. If the vendor record must be changed, follow a documented Zocdoc support path rather than inventing an API workaround or substituting another status.

Do not delete the stale item simply to clear a queue. Keep a technical audit trail with timestamps, synthetic or opaque identifiers, attempt count, response category, and reviewer outcome. Limit access and retention according to the clinic’s approved policy.

Reporting should expose the uncertainty. A dashboard may count a clinic-confirmed outcome separately from a vendor-confirmed update. For rate definitions and denominator choices, see how to calculate no-show rate by booking source. The status API alone does not define the whole metric.

How can retries avoid duplicates and false success?

Make each attempt refer to the same Zocdoc appointment and intended status. Before retrying, reload current local state and check whether a prior attempt already succeeded. A worker that loses its acknowledgement should not create a second local outcome or send contradictory updates without review.

Bound retries by both error class and time eligibility. Authentication problems, invalid identifiers, contract rejection, and a temporary connection failure are not the same condition. Preserve the shortest useful response evidence without copying request content that can expose patient information.

Use a dead-letter or review state for unresolved work. Include the reason that automation stopped, such as “outside documented no-show window” or “current vendor result unknown.” Avoid a generic failure flag that invites an operator to press retry after the action has become ineligible.

If visit-reason mapping is also failing, resolve it as a separate contract. The guide to mapping Zocdoc visit reasons to EHR appointment types explains that boundary. A mapping defect is not evidence that attendance should change.

How should the behavior be tested?

Use Zocdoc’s documented testing data and an approved non-production setup for baseline contract checks. Create only synthetic appointments. The test record should contain a neutral identifier and the minimum scheduling fields needed by the sandbox, never a real patient name, contact detail, visit reason, insurance value, or clinical note.

Test the eligibility function locally with a deterministic clock and synthetic timestamps. Cover a future start, a recent past start, and a start outside the documented two-day condition. Confirm the first and third cases do not call the vendor client and the stale case enters review. Zocdoc’s Testing Data guide does not document a clock-control fixture for this window.

Also simulate a temporary transport failure around the local boundary. Verify the retry uses the same synthetic appointment, does not create a duplicate local outcome, and stops if the deterministic clock moves beyond eligibility. If an end-to-end sandbox test of the outside-window response is required, obtain a supported fixture or procedure from Zocdoc first. Record API response metadata without storing patient payloads.

Finally, test an arrived result separately from no_show. The goal is to prove that the workflow follows an authoritative disposition, not the mere passage of time. Keep any edge interpretation of “two days” out of production until confirmed by documentation or Zocdoc support.

What evidence should operators and reviewers see?

An operator needs scheduled start, local outcome, eligibility result, last attempt time, response category, and next action. A reviewer needs the source rule and a trace showing why automation sent, retried, or stopped. Neither view requires patient or clinical content.

Use clear labels: “eligible and queued,” “vendor update confirmed,” “delivery uncertain,” and “outside documented window.” These labels prevent a locally observed no-show from being presented as a completed external update.

Monitor the age of unresolved candidates so the team can act before they become stale. This is a clinic-defined operational control, not a new Zocdoc guarantee. Report volume and outcome by booking source without changing the original source when staff resolve an exception.

Frequently asked questions

Can no_show be sent before the appointment starts?

No. Zocdoc documents that the appointment start must be in the past for a no_show update. Wait for an authoritative post-appointment outcome rather than scheduling the status in advance.

Does Zocdoc define the no-show window as 48 hours?

The cited guide says the appointment start can be no more than two days old. It does not restate that boundary as 48 hours. Do not substitute an interpretation without confirmation.

Should a stale no-show update keep retrying?

No. Once the request is outside the documented condition, move it to a visible review state. Preserve local evidence and do not claim the Zocdoc status was updated.

Is an unconfirmed appointment automatically a no-show?

No. The Zocdoc glossary describes a no-show as a patient who did not appear for a confirmed appointment. Cancellation, reschedule, uncertainty, and delivery failure require their own states.

References

Does NexHealth Send a Webhook When EHR Sync Turns Red?

Do not assume NexHealth sync-status webhooks reliably announce every change from green to red. For read sync, the Webhook Subscriptions reference documents red-to-green recovery and says green-to-red does not trigger the event. For write sync, the page’s prose says recovery-only while its example shows sync_status_write_change.red with write_status set to red. That contradiction needs NexHealth confirmation before a team relies on write-side event direction.

The safer documented monitoring path is to inspect GET /sync_status and evaluate read_status_at and write_status_at. Those timestamps need context because NexHealth warns that activity outside business hours, especially on weekends and holidays, can make them appear several hours or days old. Webhooks and polling therefore provide different evidence.

What do NexHealth sync-status webhooks actually report?

NexHealth lists separate events for read and write functionality. The documented read event fires when an integration’s read status moves from red to green. The page’s prose assigns the same recovery direction to write functionality, but its write example instead uses sync_status_write_change.red and reports write_status as red.

The source explicitly says the read webhook does not currently trigger from green to red. Its write prose makes the same statement, yet the contradictory example prevents a categorical write-side conclusion. Treat read failure notification as absent and write failure notification as undocumented until NexHealth resolves the conflict.

Do not treat either event as a complete uptime feed. A recovery event can confirm a return to service after NexHealth observes the transition, but it cannot prove when the red state began. A possible write-red event does not establish a complete delivery guarantee either. Detect degraded connectivity through an independent status check.

This differs from appointment delivery behavior. The guide to Zocdoc webhook retry boundaries concerns transport acknowledgement for appointment events. A NexHealth sync-status event concerns EHR integration health. Keep those two kinds of monitoring separate.

Why is waiting for a green-to-red event unsafe?

A webhook-only monitor can remain quiet while reads are red because the missing transition is documented behavior. Write-side silence is also ambiguous because the source conflicts about failure events. It can mean the integration stayed healthy, no relevant event occurred, or a failure was not delivered to the listener.

That ambiguity matters for scheduling. If reads are degraded, the application may not have current appointments or unavailability blocks. If writes are degraded, a booking request may not reach the connected record system as expected. Neither condition should be translated into a positive claim merely because no webhook arrived.

Operational inference: use the status query as the failure-detection input and treat webhooks as supplementary transition signals. Confirm write-event direction with NexHealth before making it a control dependency. This is not a polling interval prescribed by NexHealth. Each team must choose a cadence that fits its booking risk, API limits, business hours, and incident process.

If a status problem first appears as an empty availability response, also inspect the scheduling inputs. NexHealth availability can be empty despite an open EHR calendar when working hours or appointment-type assignments do not qualify. Sync health and availability configuration are related evidence, not interchangeable diagnoses.

How should GET /sync_status be monitored?

The sync-status endpoint can be scoped by institution through subdomain. Its documented query options include read status, write status, and location identifiers. That lets a monitor ask about the exact integration scope used by the booking flow instead of reducing every location to one account-wide light.

Track read and write independently. A location can need fresh read state for availability while also needing working write state for appointment creation or changes. One green value should not hide a red value in the other direction. Display both status and the corresponding last-success timestamp.

Store a technical snapshot rather than a patient payload. Institution alias, location scope, observed read state, observed write state, timestamp ages, request result, and monitor time are enough for the health question. Patient names, contact details, appointment reasons, notes, and insurance data add no value to this test.

A status monitor also should distinguish a successful API response from a healthy integration. An HTTP response can carry a red status. Conversely, a failed status request leaves health indeterminate rather than proving the EHR is red or green. Preserve those states separately in alerts.

How do off-hours delays change alerting?

NexHealth warns that read_status_at and write_status_at can show delays of several hours or days outside business hours, particularly on weekends and holidays. An old timestamp alone is not enough to declare an outage without considering whether the connected practice was expected to generate activity.

This warning does not mean stale timestamps should be ignored. It means the monitor needs context. A timestamp that is normal for a closed office may be suspicious during active booking hours. Use the practice’s documented schedule as an operational input, not a vendor-wide threshold invented for every location.

Operational inference: alert on a combination of state, timestamp age, expected activity, and failed business operations. Keep the rule visible to clinic IT so a holiday schedule can be explained without silencing a genuine write failure.

Working hours themselves have a separate role in availability calculation. The article on NexHealth appointment validation outside working hours explains why an accepted API call and a valid booking slot are different claims. Do not reuse clinic hours as proof that sync is healthy.

What should the booking flow do while status is uncertain?

Make uncertainty explicit. If current EHR reads cannot be established, do not convert missing busy records into free time. If write health is red or unknown, do not present a local request as a completed EHR booking. The safest user-facing state is pending, unavailable, or under review, according to the clinic’s approved workflow.

Do not silently switch to a different calendar or operatory. A fallback may have different scope and may create a duplicate appointment. The discussion of overlapping operatories in NexHealth availability shows why resource identity must remain attached to a time.

Separate read controls from write controls. A practice might decide that existing appointments remain viewable from a recent local mirror while new bookings pause. Another practice may require the whole scheduler to close. NexHealth documents the status surfaces, but the acceptable degraded mode belongs to the clinic and its application.

Show operators which capability is affected. “Integration issue” is too broad. “EHR reads are red; online slots paused” or “EHR writes are indeterminate; requests held for review” makes the state actionable without exposing appointment content.

How should recovery be reconciled after red turns green?

A red-to-green read webhook confirms the documented recovery transition. A red-to-green write event is also consistent with the page’s prose, despite its contradictory red example. Neither proves that every operation attempted during degradation reached the EHR or that the local mirror is complete. Treat a recovery signal as a trigger to start reconciliation, not as automatic closure.

Review the bounded interval between the last trusted success and observed recovery. Compare queued or uncertain technical operations with current EHR state through approved identifiers. Do not replay every request blindly. A booking may have succeeded before connectivity became uncertain, and an unconditional replay could create a duplicate.

Operational inference: make reconciliation idempotent and preserve the original booking lineage. A recovered write should not become a new acquisition event or replace the original channel. The distinction in appointment source versus marketing source remains valid during incident recovery.

Close the incident only when current status is known, affected locations are checked, uncertain operations have an outcome, and availability is based on refreshed state. The recovery webhook is one piece of that evidence.

What controlled test proves the monitoring design?

Use a sandbox or approved non-production integration with synthetic records. Test read and write monitoring separately. The goal is not to force a production EHR outage. It is to prove how the application behaves when the status endpoint reports red, when the endpoint itself fails, and when a recovery event arrives.

  1. Capture a known green read and write state for one controlled location.
  2. Feed the monitor a controlled red read state and verify availability fails closed.
  3. Feed it a controlled red write state and verify new writes remain visibly uncertain.
  4. Test an unavailable status endpoint and confirm the state becomes indeterminate.
  5. Deliver a red-to-green recovery event and verify reconciliation starts.
  6. Confirm no test record contains real patient or clinical information.

Also test off-hours context. A delayed success timestamp during a configured closure should follow the documented alert rule, while an explicit red state should remain visible. Record the exact status inputs and resulting control decision so reviewers can reproduce the outcome.

Frequently asked questions

Does NexHealth send a webhook when read status changes from green to red?

No. The current Webhook Subscriptions reference says the read-status webhook fires from red to green and does not currently trigger from green to red. Use the sync-status endpoint to monitor the failure state.

Are read_status_at and write_status_at outage timestamps?

They are last-success timestamps used to assess sync health, but NexHealth warns they can lag outside business hours. Interpret their age with location schedule and current status rather than treating any delay as a confirmed outage.

Does the write-status webhook report a change from green to red?

The current reference is internally inconsistent. Its prose says the write event reports red-to-green recovery and does not trigger green-to-red, while its example shows a red write event. Ask NexHealth to confirm current behavior and monitor GET /sync_status instead of depending on one interpretation.

Should missing EHR reads be treated as open availability?

No. Missing or indeterminate calendar state is not evidence of free time. Pause or qualify availability according to the clinic’s approved degraded-mode policy until current read health and calendar coverage are established.

References

Why Did Google Calendar Return 410 Gone During Incremental Appointment Sync?

Google Calendar returns HTTP 410 Gone during token-based incremental sync when the stored syncToken is no longer valid. Google says token invalidation can follow expiration or related access-control changes. The required recovery is to clear the client’s synchronized calendar store and run a new full sync to obtain a fresh token.

For an appointment integration, “clear the client store” should mean the local Google Calendar mirror built from that token. It should not mean deleting the clinic’s source-of-record bookings, webhook evidence, marketing attribution, or other independent records. That boundary is an operational interpretation that must be designed and tested before the first 410 occurs.

Why does an incremental sync token return 410 Gone?

Google’s synchronization guide says an invalidated token produces HTTP 410. It names token expiration and changes in related access-control lists as reasons a token may become invalid. The server can no longer use that token as a reliable cursor through the calendar’s change history.

A 410 is therefore different from “no changes.” An empty incremental result can mean the token remains valid and nothing in scope changed. A 410 means the client must stop using that cursor. Retrying the same request with the same token does not satisfy Google’s documented recovery.

Do not assume the event list itself is damaged. The error concerns the synchronization cursor and local incremental state. Rebuilding that state is expected behavior in a long-running integration, so the recovery path belongs in normal application logic rather than an emergency script.

If the problem happened while computing availability rather than mirroring event changes, use why a Google Calendar FreeBusy error is not an open provider slot. FreeBusy queries and sync tokens solve different problems.

Does every Google Calendar 410 mean the same thing?

No. Google’s error guide documents more than one 410 scenario. A request using an invalid syncToken or updatedMin requires the client to wipe its synchronized store and synchronize again. A delete request for an event that is already deleted can also return 410, but Google says no further action is needed for that delete.

Classify the operation before choosing a remedy. If the failing request is an incremental event-list call with syncToken, start a full resync. If the failing request tried to delete one event and the response says it is already deleted, do not erase the whole mirror.

Operational inference: attach an operation type to each error record: incremental list, full list, event delete, or another Calendar action. Status code alone is too coarse. The same number can lead to very different safe responses.

Keep the distinction visible in alerts. “Calendar API 410” sends an operator toward guesswork. “Incremental list token invalidated, mirror rebuild started” states the condition and action without exposing event content.

What should be cleared before the full resync?

Google instructs the client to clear its store and perform a full sync after token invalidation. In an appointment system, the store tied to the token is usually a local mirror of Google event state. Its records can be rebuilt from the authorized calendar. Independent booking records need a different retention and deletion contract.

Define that boundary in code and data ownership. A table or cache populated exclusively by Google sync may be replaceable. An appointment record created by the clinic, a payment record, consent evidence, or original booking-source attribution is not merely a sync cache. Do not cascade a calendar reset into those systems.

Operational inference: mark the affected calendar mirror as rebuilding before clearing it. While rebuild is incomplete, fail closed for slot publication if the mirror participates in availability. A partially repopulated calendar should not be presented as a complete free-time view.

Google Calendar can also be a secondary blocking calendar for another scheduler. The article on secondary Google calendars not blocking Jane online booking shows why calendar coverage must be proven at the actual scheduling boundary.

How should a new full sync be performed?

A full sync retrieves the calendar collection page by page. Google’s guide says the last page includes nextSyncToken. The client must finish every page before treating the new full sync as complete and before replacing its stored token.

Build the replacement mirror in a recoverable way. One option is a separate generation that becomes active only after all pages succeed. Another is a transaction or checkpointed rebuild suited to the local data size. These are operational designs, not Google requirements. The acceptance condition is that incomplete data never masquerades as a completed calendar.

Use the approved full-sync query parameters consistently across pagination. Preserve the page token until the final page arrives. If a middle page fails, do not store a token from an earlier page as though it represented the completed collection.

Once the final page is applied, persist its nextSyncToken with the calendar identity, sync generation, completion time, and relevant query configuration. Keep the token out of logs when it can be correlated through an internal fingerprint.

How do incremental pages and deletions affect correctness?

Google’s synchronization guide says incremental sync returns entries changed since the previous token, including deleted entries. It can also paginate. Every page in one incremental cycle belongs to the same cursor progression, and the new nextSyncToken arrives on the final page.

Apply deleted entries to the local mirror rather than filtering them out before state reconciliation. Otherwise an event removed in Google can remain as a permanent false block. A deletion in the mirror does not automatically mean deleting an appointment from the clinic’s source system. It means Google’s current calendar representation no longer includes that event.

Operational inference: make page application idempotent and save a completion checkpoint. If the worker crashes after page two, replay should not duplicate events or expose a half-applied sync. Advance the durable sync token only when the full page chain has succeeded.

Do not change the incremental query shape casually. Google’s guide restricts query parameters used with sync tokens. Treat the token and the request configuration that produced it as one sync contract. A different filter belongs to a new full-sync generation.

What recovery sequence protects appointment availability?

The recovery should make uncertainty explicit. Stop publishing availability that depends on the stale mirror, preserve the 410 evidence, invalidate the local token, rebuild from a full sync, and reopen only after the new generation is complete. Do not interpret the empty rebuilding store as a calendar with no busy events.

  1. Confirm the failed operation is a token-based incremental list request.
  2. Mark the affected calendar mirror unavailable or rebuilding.
  3. Discard the invalid sync token.
  4. Clear or replace only the token-bound mirror.
  5. Run a full paginated sync and process deleted states correctly.
  6. Persist the final page’s nextSyncToken.
  7. Compare mirror coverage with the expected calendar before republishing slots.

If the clinic’s booking engine has another authoritative availability source, it may use that source under an approved rule. Do not invent a silent fallback during an incident. Operators and patients should not see stale Google-derived openings presented as current.

Availability evidence also should not rewrite acquisition evidence. See appointment source versus marketing source before allowing a resynced event to replace the original channel.

How can the 410 recovery be tested?

Use a synthetic calendar with neutral event titles and no real patient information. Build an initial full sync, store the resulting token, and confirm one incremental change. Then simulate the application’s 410 branch with a controlled invalid-token response or approved test seam.

The test should prove more than a second API call. Verify that the old mirror is marked incomplete, authoritative appointment records remain untouched, all full-sync pages are applied, deleted entries reconcile correctly, and the final page supplies the only newly stored token.

Interrupt one rebuild between pages. On restart, the system should resume or safely restart according to its documented design without publishing partial availability. Then test a 410 from an already-deleted event operation and confirm it does not trigger the incremental-sync reset branch.

Preserve technical evidence: calendar identifier or approved alias, sync generation, operation type, page count, response status, token fingerprint, start time, completion time, and result. Keep event titles, descriptions, attendees, patient names, contact details, and clinical notes out of general logs.

What monitoring catches a broken sync early?

Monitor the age of the last completed sync, the age of the active token, consecutive failures, rebuild duration, expected versus mirrored calendar identity, page count, and whether availability publication is blocked. These are operational indicators. Google does not prescribe their alert thresholds.

A healthy HTTP response is not enough. The integration must reach the final page and save its token. An alert should distinguish a fetch in progress from a completed generation, and a dashboard should not label a calendar current while its replacement mirror is rebuilding.

Track booking outcomes separately from synchronization health. The clinic booking outcome taxonomy for Google Ads helps keep a calendar recovery from being counted as a new lead, cancellation, or conversion.

Close the incident after a controlled incremental change appears in the rebuilt mirror and availability uses the complete generation. Document why the token became unusable if known, but do not delay the required full sync while trying to prove expiration versus an access-control change.

Frequently asked questions

Can I retry the same sync token after HTTP 410?

No. Google says an invalid sync token requires a full synchronization. Discard the token, rebuild the token-bound local store, and save the new nextSyncToken from the final page.

Should a 410 delete the clinic’s appointment database?

No. Google’s instruction concerns the client’s synchronized calendar store. Keep the Google mirror separate from authoritative bookings and other records, then rebuild only the state derived from that calendar sync.

When should nextSyncToken be saved?

Save it after the final page of a successful full or incremental sync. A token from an incomplete page sequence cannot prove that the local mirror includes the complete change set.

Are deleted Google events included in incremental sync?

Yes. Google’s synchronization guide says incremental results include deleted entries. Apply them to the calendar mirror so a removed event does not remain as a false busy block.

References

Why Does Zocdoc Not Retry an Appointment Webhook After HTTP 500?

Zocdoc does not retry an appointment webhook because your endpoint returned HTTP 500. Its webhook guide states that retries depend on transport failure: Zocdoc could not connect, received no response within five seconds, or lost the connection before a response arrived. The status code in a completed HTTP response is not a retry trigger.

A receiver that sends 500 after a database or queue failure can therefore lose the update if it expects Zocdoc to deliver it again. The safer operational design is to authenticate the webhook, persist enough verified event data for recovery, and only then complete the response. That design is an implementation recommendation, not a promise made by Zocdoc.

Why does HTTP 500 not cause another delivery?

Zocdoc’s Webhooks guide says the service does not retry based on the HTTP status code returned by the receiving endpoint. A 500 response tells your own monitoring that the handler failed, but it does not meet Zocdoc’s documented conditions for another attempt.

This can feel counterintuitive because many webhook providers treat a non-success status as a negative acknowledgement. Zocdoc documents a different boundary. Once it establishes a connection and receives a response within the time limit, the response code does not decide whether the event enters the retry schedule.

A concrete failure sequence is short. The endpoint verifies a request, tries to write to a queue, the queue write fails, and the handler returns 500. If the connection stayed intact and the response arrived within five seconds, the receiver should not wait for another Zocdoc delivery. It needs its own evidence and recovery procedure.

This transport rule is separate from which appointment changes produce webhooks. Read which Zocdoc cancellations and reschedules trigger a webhook before diagnosing a missing event. Sometimes no webhook is expected because the initiating path should use the API response.

Which failures does Zocdoc retry?

The guide lists three retry conditions: Zocdoc cannot connect to the endpoint, no response arrives within five seconds, or the connection is severed before Zocdoc receives a response. For those failures, Zocdoc retries with exponential backoff for up to 48 hours after the first attempt.

These rules create two distinct risks. Respond too slowly and Zocdoc may retry while the original handler continues to work. Respond quickly with 500 and Zocdoc may not retry at all. The receiver must tolerate duplicate delivery without using an error status as a request for redelivery.

Operational inference: make event handling idempotent. A repeated event should lead to the same appointment state rather than applying the transition twice or sending another message. The guide to preventing duplicate appointment reminders covers one downstream consequence when retries are not contained.

Do not deliberately hold the connection open or interrupt it to force a retry. That relies on transport behavior as a queue, can create concurrent attempts, and offers no durable record inside your system. Build recovery where your team can observe and control it.

How should the signature and timestamp be checked?

Zocdoc documents HMAC verification with the shared webhook key and SHA-256. It also instructs receivers to extract the webhook timestamp and reject stale requests. The guide shows five minutes as the default timestamp tolerance. These checks belong before a message can affect appointment state.

Use the exact request material required by the current Zocdoc algorithm. Do not parse and reserialize JSON before computing the signature if the documentation requires the received payload form. A harmless formatting change can produce different bytes and a failed HMAC comparison.

Compare signatures in a timing-safe way available in the implementation language. Keep the shared key in an approved secret store, never in source control or general logs. A failed signature or stale timestamp should stop processing and create a security signal without printing the key or full patient payload.

Operational inference: log a one-way event fingerprint, receipt time, verification outcome, and reason code. That is usually enough to correlate repeated delivery without copying names, contact details, visit reasons, or other patient information into observability tools.

Where should the durable acknowledgement boundary sit?

Zocdoc’s five-second response boundary favors a short receiver. A common operational pattern is: verify the request, write a compact event record to durable storage or a durable queue, and then respond. A worker applies the appointment update after the event is safe from process crashes.

This pattern is an engineering recommendation. The cited source defines delivery, verification, and retries, but it does not require one queue product or database design. The durable step must fit the practice’s security, privacy, retention, and availability requirements.

Do not acknowledge first and keep the only event copy in memory. If the process exits after the response, Zocdoc has completed a non-retryable delivery from its point of view. At the other extreme, do not perform long downstream work before responding if that work can exceed five seconds and provoke concurrent retries.

The stored event needs an idempotency boundary. Use a stable event fingerprint or documented event identifier when available, plus the relevant appointment and update type, without treating patient content as the deduplication key. Preserve the original booking lineage using the method described in preserving booking source after a reschedule.

How should processing failures be recovered?

A worker failure after durable receipt should move the event into a visible retry or review state. It should not disappear, and it should not depend on Zocdoc sending the request again. Record attempt count, last error category, next action, and final resolution without storing sensitive payload fields in general logs.

Operational inference: use bounded internal retries for temporary dependencies, then quarantine the event for review. Before replay, compare current local appointment state with the event’s intended transition. An old update may no longer be safe to apply mechanically after later changes.

A reconciliation job or operator check should compare provider-originated appointment changes with the local state using an approved API path. The Zocdoc webhook page establishes which provider updates can be notified, but it does not define your full reconciliation schedule. Document the clinic’s acceptable delay and escalation owner.

Do not turn a missing update into a new appointment. Duplicate booking is not a repair for uncertain state. If visit-reason mapping is part of the failure, inspect the guide to mapping Zocdoc visit reason IDs to EHR appointment types before replaying the write.

When should the API response update local state instead?

Zocdoc’s patient-booking guidance says webhook notifications cover provider-initiated appointment changes. Developer-initiated and patient-initiated actions use their API response as the evidence path. An integration should not wait for a webhook that the documented flow does not promise.

That initiator boundary avoids false missing-webhook incidents. If your application called an API to cancel or reschedule an appointment, store the result from that call and reconcile its outcome. Reserve webhook handling for the provider-side changes that Zocdoc sends.

Keep the evidence paths distinct but converge them into one appointment state machine. The same transition may arrive from an API response in one scenario and a verified webhook in another. Both paths need idempotency, audit history, and protection against an older result overwriting a newer state.

Acquisition attribution is a different field. A provider-initiated change should not replace the original channel with “webhook.” See appointment source versus marketing source for a clean separation between operational event origin and marketing origin.

What test demonstrates the HTTP 500 behavior?

Use Zocdoc’s supported test environment and synthetic appointment data. Configure a receiver that records only technical evidence. Never use a real person’s name, phone number, email, reason for visit, or clinical notes to prove retry behavior.

  1. Send a valid signed test event and confirm signature and timestamp verification.
  2. Return HTTP 500 within five seconds while preserving receipt evidence.
  3. Confirm that your system does not assume another delivery will arrive.
  4. Exercise a transport failure that matches a documented retry condition.
  5. Confirm repeated delivery produces one final state.
  6. Recover a durably stored event through the internal review path.

The test should distinguish what Zocdoc sent from what your receiver did. Capture connection outcome, response timing, response status, fingerprint, verification result, queue result, and processing result. Keep secrets and patient content out of the record.

Pass only when the 500 case remains visible without an expected provider retry, the retryable transport case is idempotent, and the stored event can be recovered. A unit test of the handler alone does not prove proxy timeouts, queue durability, or production monitoring.

What should an incident report preserve?

Record the webhook receipt time, endpoint and deployment version, connection outcome, response latency, status code, HMAC verification result, timestamp result, event fingerprint, durable-write result, worker outcome, and reconciliation decision. That sequence shows where the event stopped.

Avoid full request dumps. If a restricted forensic copy is required under clinic policy, keep it in the approved clinical or security boundary with limited access and retention. General application logs should use technical identifiers and redacted metadata.

Write the root cause plainly. “Returned HTTP 500 after queue failure and expected Zocdoc retry” is actionable. “Webhook missing” is not. Attach the source contract and the local test that proves the corrected acknowledgement boundary.

Finally, check outcome reporting. A recovered cancellation or reschedule should not create a second acquisition or booking conversion. The clinic booking outcome taxonomy provides a related reporting boundary.

Frequently asked questions

Will Zocdoc retry when my endpoint returns HTTP 500?

No. Zocdoc states that it does not retry based on the returned HTTP status code. A 500 response should trigger your own monitoring and recovery path, not an expectation of another webhook.

How long can Zocdoc retry a transport failure?

The Webhooks guide says retryable failures use exponential backoff for up to 48 hours after the first attempt. The receiver must still handle repeated events idempotently.

What response time avoids a timeout-based retry?

Zocdoc lists no response within five seconds as a retry condition. Keep the synchronous path short, but verify the signature and persist the event before acknowledging it under your approved design.

Do patient-initiated changes always produce a webhook?

No. For the patient-booking use case, Zocdoc says provider-initiated changes produce webhook notifications. Developer- and patient-initiated actions should update local state from the API response.

References

Why Does NexHealth Return Only One Operatory for the Same Available Time?

NexHealth can return only one operatory for a time that is open in several operatories because overlapping_operatory_slots defaults to false. The Available Slots reference says the endpoint returns one slot when the same time is available in multiple operatories. Set that parameter to true when the booking flow must receive every eligible operatory for the time.

The flag changes the response, but it does not remove the need to respect scope. Location, provider, operatory, appointment type, and local time still determine what the returned option means. A booking interface that groups records by clock time alone can erase the distinction again after the API has supplied it.

What does the endpoint return by default?

NexHealth’s Available Slots guide says that when the same appointment time is available in multiple operatories, only one slot is returned. The endpoint reference explains the switch behind that behavior: overlapping_operatory_slots is a Boolean query parameter whose default value is false.

This is a response contract, not evidence that the other operatory is occupied. A practice may confirm two open rooms in its scheduling system and still see one API choice for 10:00. Under the documented default, NexHealth chooses the first available operatory it finds for that overlapping time.

The distinction matters during diagnosis. If the response contains one operatory, do not start by changing working hours or creating duplicate availability. First capture the exact request and check whether the overlapping flag was absent or false. The separate guide on empty NexHealth availability despite an open EHR calendar covers cases where no eligible slot is returned at all.

Operational inference: record the query parameter explicitly in test fixtures, even when the application wants the default. That makes the intended behavior visible during review and prevents a library update or request builder from hiding whether the flag was sent.

How does overlapping_operatory_slots change the response?

When overlapping_operatory_slots is true, NexHealth says it returns all available slots for operatories at a given time instead of only the first one found. The option is useful when the application needs to preserve operatory choice, allocate rooms under its own approved rule, or show separate eligible resources.

The flag does not promise that every configured operatory will appear. It asks for all operatories that qualify under the rest of the request and scheduling configuration. An operatory outside the requested scope, without matching availability, or without the required mapping should not be inferred from another operatory’s result.

Compare two otherwise identical requests. Send the first with the parameter false and the second with it true. Use the same location identifiers, provider identifiers, appointment type, operatory filters, date window, and API version. A controlled comparison isolates the documented behavior better than comparing two calls made from different screens.

Be careful with a UI that deduplicates options. If the API returns two records and the application stores them in a map keyed only by 10:00, one record can overwrite the other. That would be a local data-shaping defect, not a NexHealth availability result.

Which request fields still control operatory scope?

The endpoint reference requires location scope through lids[] and provider scope through pids[], unless an appointment_type_id supplies the required scheduling context. The request can also include operatory_ids[]. NexHealth advises using those operatory identifiers when operatories are mapped in the practice management system.

Arrays make multi-resource searches possible, but they also make an accidental mismatch less obvious. A request can ask for the intended provider across the wrong location, or it can carry an operatory ID that belongs to a different configuration. Preserve the exact arrays and compare them with the response fields.

Appointment type affects slot length. The View available slots endpoint reference states that supplying appointment_type_id sets slot_length to the appointment type’s minutes. Without that field, a manually supplied slot_length applies, or the endpoint uses its documented 15-minute default. Two records that start at the same clock time may therefore belong to different booking contexts. Do not merge them merely because their displayed label matches.

Provider working-hour validation is another boundary. If the issue is a returned time outside the intended schedule, use NexHealth v3 appointment validation against working hours. The operatory overlap flag answers which eligible resources are returned, not whether a later appointment write should bypass scheduling rules.

Why is the clock time alone an unsafe identifier?

NexHealth documents that returned slot times use the location’s local time zone. A text value such as 10:00 only has meaning when it stays attached to the location and date. The response also carries provider, location, and operatory context. Those fields distinguish two resources that happen to share a start time.

A concrete synthetic example shows the risk. Suppose operatories A and B both qualify for the same provider at 10:00 in one location. With the flag false, the response may expose only A. With the flag true, the client may receive A and B. If the client reduces both records to one display string, it has recreated the default even though the API returned both choices.

Operational inference: use a composite internal key built from the returned scheduling identifiers and time, rather than a patient-facing time label. Keep that key through selection, confirmation, and write-back. Do not fabricate an operatory after the user selects a time.

This same separation helps attribution. An operatory is a scheduling resource, not a marketing source. The guide to appointment source versus marketing source explains why operational routing fields should not replace acquisition fields.

How should a booking flow preserve the returned choice?

First decide whether the user should choose an operatory or whether the application may allocate one under a documented clinic rule. If the choice matters, request overlapping operatories and keep separate options. If the clinic treats eligible rooms as interchangeable, it may choose a deterministic allocation rule, but that rule comes from clinic operations, not the NexHealth source.

Show only the information a patient needs. Internal operatory IDs rarely belong in a public label. The application can retain the ID while presenting a neutral time and location. When the user confirms, submit the exact selected resource context rather than repeating availability and guessing which record corresponds to the display.

Operational inference: perform a final availability check close to booking and handle a rejected choice without silently moving the appointment to another operatory. Availability can change between search and confirmation. This article does not claim a specific NexHealth reservation guarantee; follow the current appointment creation contract for the write.

After a successful booking, keep reminders idempotent. A resource-level retry should not create a second patient message. The workflow in preventing duplicate appointment reminders addresses that downstream problem.

What controlled test proves the behavior?

Create a synthetic scheduling case with one provider, one location, and two mapped operatories that are eligible for the same interval. Do not use a real patient’s appointment or clinical details. Record only the technical identifiers needed to reproduce the request.

  1. Confirm both operatories are eligible for the same local date and start time.
  2. Send one request with identical scope and overlapping_operatory_slots=false.
  3. Record the returned location, provider, operatory, and time fields.
  4. Repeat with overlapping_operatory_slots=true.
  5. Verify that the second response preserves the separate operatory results.
  6. Pass both results through the booking UI and confirm that local deduplication does not remove one.

Test one negative case too. Filter to a single mapped operatory and confirm the response does not invent the second resource. The overlap flag broadens representation of eligible matches; it should not defeat explicit request scope.

If the second API response contains both records but the interface shows one, inspect the client transformation. If the API still returns one, preserve the full request and response, confirm mappings, and escalate to NexHealth with synthetic evidence.

What should logs and support evidence contain?

Useful evidence includes request time, API version, location IDs, provider IDs, operatory IDs, appointment type ID when used, date range, slot length setting, overlap flag, response status, and returned technical resource IDs. Redact authorization headers and other credentials.

Do not log patient names, contact details, appointment reasons, insurance information, or free-text notes. The availability question can be reproduced before any patient enters the flow. A support packet filled with unrelated personal data creates risk without improving the operatory diagnosis.

Keep business outcome reporting separate as well. If the practice measures whether a shown slot became a booked visit, define the result with a stable taxonomy such as clinic booking outcomes for Google Ads. That report should not depend on which room appeared first in an API response.

Close the incident only after the API and interface both pass the same controlled case. A correct parameter in source code is not enough if an intermediary drops it, and a screenshot of two rooms in the EHR is not proof that the request asked NexHealth to return both.

Frequently asked questions

Does one returned operatory mean all other operatories are busy?

No. With overlapping_operatory_slots at its default false value, NexHealth returns only the first operatory found when several have the same available time. Check the parameter and request scope before changing availability.

Should I always set overlapping_operatory_slots to true?

Set it to true when the workflow needs every eligible operatory at the same time. If one returned resource is sufficient, the default may match the product design. The clinic should decide how resource allocation works.

Can I group returned slots by start time?

You can group them for display, but do not discard location, provider, operatory, date, or time-zone context. Keep each selectable record distinct through booking so one 10:00 option does not overwrite another.

Are returned slot times in UTC?

The Available Slots guide says times are returned in the location’s local time zone. Keep the location attached to the value and apply one explicit time-zone policy in the client.

References

Which Zocdoc Cancellation and Reschedule Changes Trigger a Patient-Booking Webhook?

Zocdoc’s patient-booking webhooks do not represent every cancellation or reschedule path. In that use case, webhook notifications are sent only for provider-initiated appointment changes. When a developer or patient initiates the action through the API flow, Zocdoc tells the developer to update internal systems from the API response and not wait for a webhook.

Two other checks matter. A reschedule request is accepted only from documented appointment states. The credential used for the original booking controls who may later view or modify it. Keep the API response and any provider-originated webhook attached to the same appointment state record.

Which appointment changes produce a patient-booking webhook?

Zocdoc says its webhooks cover changes to appointment statuses for appointments booked through /v1/appointments/, including cancellations and reschedules. It then narrows the patient-booking use case: webhook notifications are sent only for provider-initiated appointment changes.

For developer- or patient-initiated actions, the instruction is different. Update the internal system from the API response and do not wait for a webhook. A booking integration that waits for every cancellation to return through the webhook channel can leave its own record stale even though the initiating API request already completed.

This is an initiator boundary, not a statement that Zocdoc has no cancellation webhooks. Identify who initiated the change and which flow handled it. Keep that evidence with the appointment state, not in marketing attribution. The article on booking systems versus CRM ownership explains why operational truth should not be reconstructed from downstream marketing records.

What should happen after a developer-initiated change?

When the developer or patient initiates the cancellation or reschedule, use the response from that API operation to update the internal record. Do not create a pending state whose only exit depends on a webhook that the documented patient-booking flow does not promise.

Operational inference: store the action identifier, initiator class, request time, returned appointment data or outcome, and previous local state. Apply the response through an idempotent state transition. The source directs the integration to use the API response; it does not prescribe database columns, queue design, or the exact names of local states.

If the response is ambiguous or the request fails, do not guess that the appointment changed. Re-read the appointment through an authorized path or send the case to reconciliation. Keep availability publication separate until the booking state is known. For the related upstream contract, see how Zocdoc timeslot updates replace a provider day.

What should happen after a provider-initiated change?

A provider-originated cancellation or reschedule in the patient-booking use case is the path for which Zocdoc documents webhook notification. The webhook is an external event, so the receiver must authenticate it, identify the appointment, and apply the status change without assuming delivery occurs exactly once.

Zocdoc supports HTTPS for appointment status webhooks, with HTTP allowed only for sandbox testing. Each webhook request is signed with a shared key. The guide tells clients to verify the signature so they can confirm origin and detect tampering. It also uses a webhook timestamp and recommends checking that it is within a few minutes, with five minutes shown as the default.

Operational inference: acknowledge only after the event has reached durable processing, then make the state transition idempotent. The separate guide on booking webhook idempotency and audit evidence covers that generic implementation problem. Zocdoc’s source establishes the trigger, signature, and retry contract.

Which states can be rescheduled?

Zocdoc’s Appointment Actions guide permits a time change and reschedule request when the appointment is in pending_booking, confirmed, pending_reschedule, or rescheduled. The operation uses POST /v1/appointments/reschedule with the appointment_id and new start_time.

Do not send the operation from an unlisted state merely because the local interface offers an edit button. Validate the current Zocdoc state first. If local state differs, reconcile before retrying. The source lists the states accepted for this action, but it does not authorize an integration to manufacture one locally.

Visit-reason and EHR type mapping is another boundary. A new time does not repair a mismatched clinical scheduling code. Use the documented method for mapping Zocdoc visit reasons to EHR appointment types and validate the rescheduled appointment against the same mapping.

How does cancellation differ from rescheduling?

Cancellation uses POST /v1/appointments/cancel. The documented example sends an appointment_id, a free-text cancellation_reason, and a cancellation_reason_type. Rescheduling uses its own endpoint and supplies a new start time. They are separate actions rather than two labels for the same update.

Keep the local transition and audit record distinct. A cancellation should not silently reopen a slot unless the scheduling source and availability contract establish that result. A reschedule involves the old time and the requested new time, but the cited sources do not define a clinic’s inventory reconciliation algorithm.

Operational inference: reconcile both the appointment and affected availability after the API result or provider webhook is accepted. Do not copy cancellation text into analytics, Ads, or general logs. A reason may contain sensitive context. Store only what the approved booking workflow needs.

How does the original credential affect modification access?

Zocdoc documents the same credential boundary for cancellation and rescheduling. If an appointment was booked with a Zocdoc user credential, only that user can view or modify the appointment. If it was booked with a machine-to-machine credential, any of the developer’s machine-to-machine credentials can view and modify it.

A valid access token is therefore not enough by itself. The integration must know which credential class created the booking and select an authorized credential for the later action. A 401 or 403 should not be translated into an unsupported state change or a second appointment.

Operational inference: retain non-secret provenance that identifies the booking’s credential class and accountable principal. Never store an access token in the appointment audit record. If credential ownership cannot be established, stop the mutation and reconcile through an approved support path.

What retry behavior can surprise a webhook receiver?

Zocdoc says it retries webhook events with exponential backoff for up to 48 hours after the first attempt. Retries occur when a connection cannot be established, when no response arrives within five seconds, or when the connection ends before a response. Zocdoc does not retry based on the status code returned by the webhook endpoint.

A quick HTTP response does not prove durable processing. Returning an error status does not itself request another delivery under the documented rule. Taking longer than five seconds can create a retry even when the original handler continues working. The receiver must tolerate repeated delivery and avoid applying one provider change twice.

The payload signature uses a timestamp and JSON payload, and Zocdoc notes that the schema may change. Validate required fields while allowing compatible additions. Do not disable signature checking to accommodate a parser failure.

What end-to-end test proves the initiator boundary?

Use sandbox appointments and synthetic people only. Book one appointment with the credential class under test. Record its current Zocdoc state. Exercise a developer-initiated cancellation or reschedule, then confirm that the internal system updates from the API response without waiting for a webhook.

Next, use the supported sandbox path for a provider-initiated change and verify the signed webhook. Check that the receiver validates the timestamp and signature, responds within five seconds, and applies a repeated event only once. Test user-credential and machine-to-machine bookings separately because their later modification rights differ.

Pass only when the same final state is reached through the correct evidence path for each initiator. Do not use a webhook absence as proof that an API action failed. Do not use an API success from one credential class as proof that another credential can modify the booking.

Frequently asked questions

Will every Zocdoc cancellation send a webhook?

No. In the patient-booking use case, Zocdoc says webhook notifications are sent only for provider-initiated appointment changes. Developer- or patient-initiated actions should update internal state from the API response.

Which appointment states can the reschedule endpoint modify?

The documented states are pending_booking, confirmed, pending_reschedule, and rescheduled. Reconcile an appointment in any other state before attempting the operation.

Can any valid Zocdoc token cancel a user-booked appointment?

No. If the appointment was booked with a Zocdoc user credential, only that user can view or modify it. Machine-to-machine bookings follow the separate developer credential boundary.

Does returning HTTP 500 make Zocdoc retry a webhook?

Not under the documented retry rule. Zocdoc says retries are based on connection failure, no response within five seconds, or a severed connection, not the returned status code.

References

Why a Google Calendar FreeBusy Error Is Not an Open Provider Slot

A Google Calendar FreeBusy error is not an open provider slot. The freeBusy.query response can report errors for an individual calendar or an expanded group. When that happens, the integration does not have reliable occupancy data for the affected provider. It should treat the result as indeterminate, not convert the absence of usable busy intervals into availability.

The API also places exact limits on expansion: at most 100 calendar identifiers from one group and at most 50 calendars in one query. Those limits matter in a multi-provider clinic. A request can be structurally valid while one calendar cannot be computed, cannot be found, or exceeds an expansion boundary.

What does a FreeBusy response actually establish?

Google documents POST https://www.googleapis.com/calendar/v3/freeBusy as a query for free and busy information across a set of calendars. The request supplies timeMin, timeMax, an optional response timeZone, expansion limits, and calendar or group identifiers. The returned structure separates group results from calendar results.

For a calendar that was computed successfully, the busy array contains time ranges. Google defines each busy start as inclusive and each end as exclusive. An empty busy array can support a free result only when the calendar result itself is valid for the requested interval. The response shape also permits an errors array on that same calendar.

Operational inference: make result validity a separate field from the busy interval list. A calendar with no busy intervals and no error is different from a calendar whose computation failed. Collapsing both cases into an empty array creates a false opening. Jane has its own calendar coverage boundary, described in why secondary Google calendars do not block Jane online booking.

Which errors must the availability parser inspect?

The official response schema includes groups.(key).errors[] and calendars.(key).errors[]. Google lists groupTooBig, tooManyCalendarsRequested, notFound, and internalError as possible reasons. It also warns that new error types may be added, so a client cannot safely rely on a closed list.

Parse errors before turning intervals into appointment slots. A notFound result means the requested resource was not found and may point to a stale identifier. An internalError is not evidence that the calendar contains no events. Expansion errors show that the requested set was not computed within the stated boundary.

Operational inference: use a small outcome model such as valid, temporarily indeterminate, and configuration error. The Google source does not prescribe those labels. It does establish enough structure to prevent the unsafe shortcut of treating every non-busy result as free. Log the calendar reference, query window, reason, and attempt without copying event details.

How should the 100-member and 50-calendar limits be handled?

groupExpansionMax controls the number of calendar identifiers returned for one group and has a maximum value of 100. calendarExpansionMax controls the number of calendars for which FreeBusy information is provided and has a maximum value of 50. A group larger than the configured group limit returns an error.

Do not solve a limit error by dropping calendars silently. That would make omitted providers appear available if downstream code assumes the request covered everyone. Keep the expected provider set beside the returned set, and require every expected calendar to reach a valid result before publishing its slots.

Operational inference: divide a larger roster into deterministic groups of no more than 50 calendars, then merge only validated results for the same query window. If the clinic uses Google Groups, resolve and compare group membership deliberately rather than assuming one group call proves complete coverage. Chunking is an integration method derived from Google’s cap, not a workflow mandated by Google.

Why do time bounds and time zones need separate checks?

Google requires timeMin and timeMax as RFC3339 date-time values. The optional timeZone controls the zone used in the response and defaults to UTC. These fields describe the query and presentation window. They do not decide the clinic’s appointment duration, buffer rules, provider location, or booking horizon.

Compare the returned timeMin and timeMax with the requested range before generating openings. Normalize intervals to one approved scheduling zone, then apply clinic rules after occupancy is known. A UTC response is not wrong, but displaying or slicing it as local time without conversion can shift a busy interval into the wrong provider day.

Operational inference: test local midnight and local clock changes for every operating zone. The source defines the API fields, not the clinic’s time-zone policy. Keep that policy explicit and avoid browser-derived defaults in server-side availability calculations.

What permission is sufficient for occupancy checks?

Google’s calendar-sharing documentation defines freeBusyReader as permission to see whether a calendar is free or busy without access to event details. The role can use freeBusy.query. This is narrower than reader, writerWithoutPrivateAccess, writer, or owner.

Use the narrow role when occupancy is the only business need. A scheduling layer does not need meeting titles, descriptions, guest lists, or other event content to subtract busy periods. Domain settings can still restrict the effective access granted to a Google Workspace user, so a configured ACL is not proof that every query will succeed.

Sharing a calendar also does not automatically insert it into a user’s CalendarList. Do not use visibility in the Google interface as the sole test of API access. Verify the exact calendar identifier and the FreeBusy result. For broader booking data boundaries, see minimum necessary fields for a booking integration.

What is a safe slot-generation sequence?

A safe sequence proves coverage before it publishes availability. Start with the expected provider calendars and one explicit RFC3339 interval. Send queries within the documented expansion limits. Inspect group errors, calendar errors, returned identifiers, and interval bounds before reading any busy array.

  1. Resolve the approved calendar identifier for every provider in scope.
  2. Split requests so no query asks for more than 50 calendars.
  3. Send identical time bounds and the approved response time zone.
  4. Reject or quarantine every group or calendar carrying an error.
  5. Subtract busy intervals only for calendars with valid results.
  6. Apply clinic duration, buffer, and booking-window rules afterward.
  7. Publish slots only for providers whose coverage is complete.

This ordering keeps calendar truth ahead of presentation logic. It mirrors the replacement-safety principle in Zocdoc provider-day timeslot updates: unknown upstream state should stop publication rather than erase or invent availability.

How should retries avoid accidental double booking?

The two cited Google pages describe the FreeBusy contract and sharing roles, not a complete retry policy for clinic scheduling. Operational inference: retry transient failures within a bounded window, but keep the affected provider unavailable until a valid response arrives. A cached result may be used only under a documented clinic policy with an explicit age ceiling.

Do not convert a retry timeout into an empty busy array. Return an unavailable or temporarily indeterminate state to the booking interface. Preserve enough evidence to diagnose the failed calendar without storing event content. If the system later publishes a slot, it should use a fresh validated query rather than the failed response.

Reconciliation should compare the provider set requested, the calendars returned, their error arrays, and the slots eventually published. After a booking exists, asynchronous updates need a different check. The guide to idempotent and auditable booking webhooks covers duplicate delivery and state reconciliation.

What acceptance test proves the boundary?

Use synthetic calendars and neutral events. First query a calendar with one known busy interval and confirm that the interval removes the expected opening. Then query an invalid calendar identifier and confirm that the provider becomes indeterminate rather than fully free. Repeat with enough test identifiers to exercise the local chunking path.

Record the request window, response zone, expected identifiers, returned identifiers, error reasons, and publication decision. Do not put patient names, treatment details, or appointment reasons into test events or logs. The test concerns occupancy and error handling, not clinical content.

Pass only when every expected provider has either a valid computed result or an explicit blocked state. A successful HTTP exchange alone is insufficient because the documented response body can carry errors for specific groups or calendars.

Frequently asked questions

Does an empty busy array always mean the provider is free?

No. It supports that conclusion only for a valid calendar result covering the requested interval. If the calendar or its group has an error, availability is indeterminate and should not become an open slot.

Can one FreeBusy request cover 70 provider calendars?

Google documents a maximum calendarExpansionMax of 50. An integration with 70 calendars should split the work into bounded requests and verify that every expected calendar produced a valid result before merging availability.

Do I need permission to read event titles?

No, not when the integration only needs occupancy. Google’s freeBusyReader role reveals whether time is free or busy without granting access to event details.

Should an internal error reopen the provider’s day?

No. internalError means the computation failed. Treating it as a free calendar would be an unsafe operational inference. Keep the provider blocked or indeterminate until a valid result is available.

References

Why Did NexHealth v3 Accept an Appointment Outside Working Hours?

NexHealth v3 can accept an appointment outside a provider’s working hours because POST /appointments no longer performs the working-hours validation used by the legacy API. NexHealth’s migration guide says an out-of-hours booking can be accepted and written back to the EHR. A successful request therefore does not prove that the selected time appeared in the current bookable-slot response.

The safe boundary belongs in the booking flow. Check the requested provider, location, appointment type, operatory, duration, and start time against GET /available_slots before submission. After submission, monitor the appointment insertion result. Keep transport acceptance, EHR completion, and patient attendance as separate states.

What changed in NexHealth v3 appointment creation?

NexHealth documents a specific breaking change in v3.0.0, also published as v20240412. The legacy v2.2.2 endpoint rejected bookings outside a provider’s synced working hours. Version 3 does not run that check. Its migration guide says those bookings are accepted and written back to the EHR.

This change affects the meaning of a successful create response. The endpoint still accepts an appointment body and returns the documented success status, but the server no longer uses working hours as a rejection gate. A client that relied on a 400 response to stop invalid selections has lost that control after migration.

The new behavior does not make working hours irrelevant. NexHealth still uses them when calculating bookable times through GET /available_slots. The difference is where validation happens. The read endpoint computes eligible choices; the write endpoint accepts the selected appointment without repeating the old working-hours check.

That distinction also separates HG074 from the related problem of an empty NexHealth availability response. An empty result asks why no options were returned. An out-of-hours write asks why creation succeeded despite the configured boundary.

How should the selected time be validated before submission?

Validate the proposed start time against a fresh GET /available_slots response for the same booking context. NexHealth says this endpoint returns bookable slots for the requested locations and date range, computed from provider availabilities and existing appointments. It requires the institution subdomain, start date, number of days, and location IDs, plus provider IDs or an appointment type.

Match more than the displayed clock time. Confirm the returned location ID, provider ID, operatory ID when applicable, and local start and end time. Separately confirm that the request used the intended appointment type and its configured duration. A 10:00 slot for one provider or operatory does not authorize 10:00 for another.

Operational inference: perform the availability check as close as practical to the create request. The official documentation says to validate against /available_slots before booking, but it does not promise to reserve a slot between the read and write. A later appointment or calendar change can make an earlier response stale.

Do not solve this by copying clinical details into the request log. A sanitized record needs the API version, institution alias, location ID, provider ID, operatory ID, appointment type ID, requested time, response status, and correlation ID. It does not need a patient’s name, phone number, reason for visit, treatment notes, or insurance information.

Why is a successful API response not the final booking state?

NexHealth describes appointment creation as asynchronous. Its Appointments reference recommends subscribing to the appointment insertion webhook, which reports complete or failed when the integration inserts the appointment into the EHR. The initial create response and the downstream EHR result therefore answer different questions.

A practical state model has at least four values: selected from current availability, accepted by the API, completed in the EHR, and later attended or not attended. The first three are technical or operational events. Attendance belongs to the clinic’s later workflow. Collapsing them into one “booked” flag hides failures and inflates acquisition reporting.

Apointoo should preserve the returned appointment identifier and a non-sensitive correlation key, then update the operational state from the insertion webhook. It should not send the appointment type, notes, patient identity, or other health context to advertising platforms. The guide to clinic booking outcome taxonomy explains why internal outcomes and ad-platform payloads need different detail.

If the insertion fails, keep the error category and timestamp without storing the raw patient payload in general logs. Route the case to the approved operational queue. Do not tell the patient or reception team that the EHR booking exists until the integration has reported completion or the practice has verified it directly.

Can availability change between the check and the create request?

Yes, that is a reasonable operational risk even though NexHealth does not document a temporary reservation created by GET /available_slots. The endpoint computes bookable time from provider availability and existing appointments. Another booking or schedule update can occur after the response and before the create request.

Operational inference: treat each slot response as a current observation, not a lock. Keep the interval between selection and submission short. When the user returns to an old browser tab, changes provider, changes appointment type, or resumes after a long pause, request availability again instead of trusting cached options.

Do not retry a create request blindly after a timeout. First determine whether NexHealth accepted the original request and whether the insertion webhook later completed it. An automatic retry without an idempotency decision can create duplicate operational work or competing appointment records. The general process for preventing duplicate appointment reminders uses the same ownership principle: one event needs one authoritative state and one controlled retry path.

If the selected slot is no longer available, return the user to a new availability result. Do not silently move the appointment to a nearby time. A different time is a different choice and may require renewed confirmation from the person booking.

What evidence should a booking integration retain?

Retain enough evidence to reconstruct the technical decision without creating a shadow patient record. For the availability check, keep the request time, API version, sanitized booking scope, and the selected returned slot. For creation, keep the correlation ID, response code, returned appointment ID, and insertion status. Apply normal retention and access controls to this operational record.

Use structured fields rather than dumping full requests and responses. Full payloads may contain patient identity, contact details, notes, or other data that belongs in the approved scheduling system. Redaction after collection is weaker than never collecting the unnecessary field. Support screenshots should also use a sandbox or synthetic appointment.

Separate the booking system’s source from the marketing source. A successful NexHealth write should not replace the campaign or channel that originally influenced the request. The article on appointment source versus marketing source gives a durable model for that distinction.

For an escalation, provide the endpoint, sanitized parameters, API version, timestamps, correlation ID, expected slot, observed status, and webhook result. State whether the time appeared in the immediately preceding availability response. That packet helps an integration team diagnose the path without exposing patient information.

How should a team test the v3 booking boundary?

Use a sandbox when available. Otherwise, obtain clinic approval for a future synthetic window that cannot displace real care. Create no patient record with a real person’s identity. Keep the test outside advertising systems and remove synthetic records through the practice’s approved cleanup process.

  1. Send every request with the intended Nex-Api-Version header.
  2. Query /available_slots for one verified provider, location, appointment type, and date.
  3. Choose a returned slot and save only sanitized request evidence.
  4. Submit the appointment once and record its response and identifier.
  5. Wait for the insertion webhook and record complete or failed.
  6. Verify the synthetic appointment in the correct EHR calendar.
  7. Test an out-of-hours time only in a controlled environment where an accepted write cannot affect a real schedule.

The pass condition is precise: the interface offers only current returned slots, submission uses the same scope, and the system does not claim EHR completion before the webhook or direct verification. A separate test should confirm that rescheduling keeps the original acquisition lineage, as described in preserving booking source after a reschedule.

Frequently asked questions

Does NexHealth v3 reject appointments outside working hours?

No. NexHealth’s migration guide says v3 removed the working-hours validation performed by v2.2.2. Out-of-hours bookings can be accepted and written to the EHR. Validate the selected time against GET /available_slots before creating the appointment.

Does HTTP 201 mean the appointment reached the EHR?

Not by itself. NexHealth describes appointment creation as asynchronous and recommends the appointment insertion webhook. Treat the create response as API acceptance, then use the webhook’s complete or failed result to track EHR insertion.

Should the integration cache available slots?

NexHealth documents available slots as bookable times computed from availability and existing appointments, but it does not document a reservation created by reading them. If the booking context or time has changed, request current availability again. This refresh rule is an operational inference, not a vendor guarantee.

Can the booking event be sent to Google Ads?

Only a separately approved, privacy-safe conversion event should enter an advertising workflow. Do not send patient identity, appointment type, reason for visit, notes, or other health data. API acceptance also should not be labeled as attendance or revenue.

References

Why Do Secondary Google Calendars Not Block Jane Online Booking?

A secondary or shared Google Calendar does not block Jane online booking because Jane’s documented inbound sync reads only the primary calendar of the connected Google account. Events on that primary calendar appear in Jane as Busy - Google Calendar Event and prevent patients from booking the covered time online. Events on other calendars in the same account do not enter Jane through this connection.

The confusion comes from treating every calendar visible in Google as one availability source. Google can show primary, secondary, shared, and subscribed calendars together. Jane does not evaluate all of them for inbound blocking. Calendar ownership, sync direction, and administrative double booking create separate boundaries.

Why do secondary Google calendars stay invisible to Jane?

Jane states that only the primary calendar for the connected Google account is synced. Events from secondary or shared calendars do not show in Jane. The primary calendar is the first calendar listed under My Calendars in that Google account. Moving between calendars in the Google interface does not change which one Jane reads.

Jane also limits each staff profile to one connected Google account. That means connecting an account with a convenient email address is not enough. Its primary calendar must be the calendar that contains the events intended to block patient booking. A team can otherwise see the event in Google, see a Connected badge in Jane, and still have no corresponding Busy block.

This is a documented coverage boundary, not proof of an intermittent failure. Operational inference: identify the event’s actual calendar before reconnecting accounts or changing shifts. Check which calendar owns it, not merely which account can view or edit it.

Keep that availability diagnosis separate from acquisition attribution. A booking that remains available because a block was absent still has its own operational source. The guide to appointment source versus marketing source explains why calendar ownership should not rewrite campaign or channel data.

What is the difference between Jane’s two calendar directions?

Jane documents two separate one-way flows rather than an automatic two-way sync. The inbound Google Calendar connection brings primary-calendar events into Jane as Busy blocks. The outbound Jane calendar subscription sends appointments or shifts to external calendar software through private iCal URLs. These flows solve different jobs and should not be used as proof of each other.

The outbound subscription is view-only. Jane says it does not change the external calendar to show the user as busy and cannot be edited to manage availability. Subscribing to a Jane feed in Google therefore does not make a secondary Google calendar an inbound blocker. It only lets the staff member view selected Jane schedule information in an external calendar.

Name the direction before testing: “Google primary to Jane” for inbound blocking, or “Jane to external calendar” for outbound visibility. Avoid calling either path “two-way” in runbooks. That label hides which system owns the event and enforces availability.

Calendar movement should not create new demand in reports. If an appointment is changed after booking, use the separate method for preserving original booking source after a reschedule while recording the later action independently.

How should a clinic identify the primary Google calendar?

Jane identifies the primary calendar as the first calendar under My Calendars in the connected Google account. Open the test event and verify its calendar field. A color, shared access, or appearance in the same weekly grid is not enough. The event must belong to that primary calendar for Jane’s documented inbound sync to import it.

If the event belongs to a secondary or shared calendar, choose an operating rule before copying it. The clinic might use each practitioner’s primary calendar, connect another account, or manage the block in Jane. Those are workflow choices. Jane’s cited guides do not prescribe one migration strategy.

Operational inference: do not duplicate a whole shared calendar blindly. Repeated and all-day events may block more time than intended, and copied events can lose their ownership context. Test one non-sensitive event first. Use a neutral title because Jane hides titles from its schedule view, but Google permissions still govern who can see the original event.

How can staff verify that a primary-calendar event arrived?

A synced Google event should appear on the Jane schedule with the label Busy - Google Calendar Event. Jane says the schedule should update after about one minute, though a page refresh may be needed. The inbound window covers events from the past 30 days through 12 months into the future.

Create or select one neutral test event on the primary calendar at a time that is otherwise offered online. Wait for the documented update period, refresh Jane, and confirm the Busy block appears at the same time. Then check the patient-facing booking path with a non-identifying test. Do not use a patient’s existing appointment or private meeting details as test content.

If the Busy block does not appear, capture the connected account, staff profile, event calendar, time zone, creation time, and refresh state. Do not disconnect first. Jane says disconnecting removes previously synced Google events from its schedule, so preserve evidence before changing the connection.

A successful block proves availability behavior for that test. It does not prove reminder ownership or message suppression. Clinics using several systems should separately test duplicate appointment reminder paths after the booking workflow is stable.

Why can staff still book over a Google Busy block?

Jane distinguishes patient online booking from administrative booking. Imported Google events block the covered time for patients online. However, if administrative double booking is enabled in Schedule Settings, staff can still create an appointment at the same time as the Google event. Seeing an internal override does not mean the inbound sync failed.

Test the two paths separately. First, use the online booking experience to confirm the time is unavailable to a patient. Second, inspect the administrative schedule and relevant double-booking setting. Record whether the staff action displayed a warning or allowed the overlap, but do not infer a specific warning behavior that Jane’s cited calendar guide does not document.

Operational inference: clinics that expect a hard internal block should review who may double-book and under which procedure. The cited sources establish that the override can exist, not which staff roles should have it or how a clinic must govern exceptions. That decision belongs to clinic policy and current Jane configuration.

What privacy details matter in Jane calendar subscriptions?

The inbound Google sync shows only Busy blocks in Jane, without the Google event title, description, or guest information. Jane says these events do not appear in reports or exports. This limits what Jane displays, but it does not turn Google Calendar into a suitable place for patient or treatment details.

The outbound iCal subscription has a different privacy concern. Jane notes that appointment notes can contain PHI or other confidential information and lets staff exclude notes through Privacy and Sharing settings. It also warns that Google Calendar subscription defaults may expose details to people who can view the Google calendar unless sharing is configured carefully.

Use neutral synthetic events, keep private calendar URLs confidential, and confirm sharing settings. An iCal URL is an access mechanism, not a public link for tickets or shared documents. Troubleshooting needs timestamps and configuration evidence, not names, contact details, reasons for visits, or clinical notes.

What is a reliable test sequence for this problem?

A reliable test proves calendar ownership, inbound import, patient blocking, and administrative override as separate outcomes. Changing several settings at once makes the result hard to explain. Use one staff profile, one connected account, one neutral event, and one otherwise bookable time.

  1. Confirm the Google account shown as Connected in the staff profile.
  2. Identify the primary calendar under that account’s My Calendars list.
  3. Create a neutral test event on the primary calendar.
  4. Wait about one minute, refresh Jane, and find the Busy block.
  5. Confirm the time is unavailable through patient online booking.
  6. Test administrative booking separately if double booking is enabled.
  7. Repeat with a secondary calendar only to demonstrate the documented coverage boundary.

Record each result without creating a real patient record. If a synthetic booking is permitted and necessary, remove it through the clinic’s approved process and preserve its test label. Later reporting should use a stable outcome taxonomy rather than treating a calendar test as a genuine booking. The clinic booking outcome taxonomy provides that separation.

Frequently asked questions

Can Jane sync a shared Google calendar for blocking?

Jane’s guide says secondary and shared calendars do not sync into Jane. Only the primary calendar of the connected Google account creates the documented Busy blocks. Shared access to an event does not make that event part of the primary calendar.

Does subscribing to Jane’s iCal feed create Busy time in Google?

No. Jane describes its calendar subscription as view-only and says it does not change the external calendar to show the user as busy. The iCal feed displays Jane appointments or shifts externally; it is not the inbound Google-to-Jane availability connection.

Why can reception book a time that patients cannot?

Administrative double booking may be enabled in Jane’s Schedule Settings. In that case, a Google event still blocks patient online booking, but staff can book administratively at the same time. Test the patient and staff paths independently before diagnosing a sync failure.

How far does Jane import Google Calendar events?

Jane says the inbound sync brings over all primary-calendar events from the past 30 days through 12 months into the future. An event beyond that window is not a valid test of current coverage. A new event should update after about one minute, though Jane may need a refresh.

References

Why Does NexHealth Return No Available Slots When the EHR Calendar Is Open?

An open EHR calendar does not automatically mean NexHealth can return online-bookable times. NexHealth documents a narrower calculation: GET /available_slots starts with configured working hours, evaluates the requested provider, location, date range, and appointment type, then removes existing appointments and calendar unavailabilities. If the first boundary is empty or the request filters out every matching record, the response can contain no slots while staff still see unused time in the EHR.

The EHR view answers whether time appears unused in the source schedule. NexHealth answers whether that time meets the integration’s booking rules. Confusing the two can hide a mismatch in working hours, appointment-type assignment, operatory scope, or request parameters.

What does an empty NexHealth availability response mean?

An empty slot list means the request produced no bookable time under the configuration and filters NexHealth evaluated. It does not, by itself, prove the EHR is full, the provider is off, synchronization failed, or the endpoint is unavailable. NexHealth’s Scheduling Configuration Guide even shows a successful HTTP 200 response with an empty slots array when active availability is missing.

The documented calculation has three main inputs: working hours define candidate time, calendar unavailabilities remove blocked time, and NexHealth appointment types determine which service can use a working-hour record and its duration. The request window and identifiers decide which records enter that calculation. A clean diagnosis checks each layer instead of using the EHR’s visual calendar as the only evidence.

Operational inference: save the response, request parameters, timestamp, API version, and relevant record identifiers before editing anything. The record will show whether a later result followed a configuration change or a different request. Keep patient-identifying screenshots and appointment details out of the support ticket.

Why can the EHR look open when working hours are missing?

NexHealth states that working hours are required before GET /available_slots can show real-time availability. Those records define when online booking is allowed. When none exist for the requested provider and location, NexHealth returns no availability even if the EHR contains a visibly open part of the day. Unused EHR space is not a substitute for a configured online-booking boundary.

Working hours may be manual or synced. Manual records are managed through NexHealth. Synced records come from supported EHR systems and are not edited in NexHealth. The source field identifies the path. NexHealth instructs users to update synced hours in the EHR.

Operational inference: query working hours for the same provider and location used in the empty slot request. Confirm that at least one active record covers the requested date and local time. Then compare its source, days, specific date, begin time, end time, provider, location, and operatory. Do not create manual hours merely to make a test pass if synced hours are supposed to be authoritative.

Mixing manual and synced working hours is possible, but NexHealth warns that overlapping records can affect returned slots. Choose the source deliberately. A practice comparing owned booking with a marketplace should also keep this technical boundary separate from the broader question of whether it needs marketplace demand or owned scheduling.

How does appointment type filtering remove otherwise open time?

An appointment_type_id does more than name the visit. NexHealth says it sets slot length from the appointment type’s minutes and restricts the calculation to working-hour records associated with that type. If no matching working hour has that type assigned, the endpoint correctly returns no slots, even when other appointment types or unfiltered requests show availability.

Compare two requests that differ only by the appointment-type filter. If the provider request returns time and the filtered request does not, inspect the type’s working-hour assignment. Confirm that the application sent the intended NexHealth type ID. A similar EHR label does not prove the records are the same.

NexHealth also distinguishes its appointment types from EHR appointment descriptors. The former controls scheduling categories, duration, and working-hour eligibility. The latter describes how a booked appointment is written into the EHR. Do not change descriptor mapping to solve an empty slot search unless separate evidence shows a write-back problem.

Keep the service selection captured as operational evidence without copying treatment details into marketing tools. The same separation used to preserve booking source after a reschedule helps here: scheduling configuration, booking lineage, and acquisition attribution should remain distinct records.

Which provider, location, operatory, and date filters should be checked?

The /available_slots request requires subdomain, lids[], start_date, days, and Nex-Api-Version, plus at least one pids[] or appointment_type_id. NexHealth recommends requesting no more than 14 days for better performance. A technically valid request can still search the wrong location, provider, date window, or working-hour source and therefore return no relevant slots.

Rebuild one minimal request from verified identifiers. Include the required subdomain, location, start date, day count, API version, and provider or appointment type. Then add working-hour source, label, and operatory filters one at a time. This sequence is an operational diagnostic method, not a NexHealth guarantee, but it makes the filter that removes availability visible.

Operatory mapping needs special care. NexHealth says operatory_id is required when a location uses map_by_operatory = true for working-hour creation or updates. Its configuration guide also says an availability query without an operatory can return only the first available operatory. That may produce an incomplete view rather than a universal no-availability conclusion.

Record scheduling source separately from marketing source while testing these identifiers. The guide to appointment source versus marketing source explains why a request parameter should not overwrite the campaign or channel that originally influenced a booking.

How do appointments and calendar unavailabilities affect the result?

After NexHealth identifies candidate time inside working hours, it subtracts booked appointments and calendar unavailabilities. The configuration guide describes an unavailable calendar record with unavailable: true; any overlapping window is excluded from /available_slots. A provider can therefore have valid working hours and still have no remaining bookable interval for the requested duration.

Compare the exact time window, not only the number of visible entries. A short opening may be too small for the appointment type’s duration. A block may overlap part of a candidate slot. A lunch gap may be represented as missing working hours rather than an explicit unavailable record. These documented models can produce similar screens but require different configuration checks.

Operational inference: use a synthetic test window approved by the practice, with no patient-identifying data. Confirm the provider, local date, duration, and expected operatory. Then inspect the working hour and any overlapping appointment or unavailability record. Do not remove a real appointment or administrative block simply to force availability.

How should a team run a controlled availability test?

A controlled test should change one variable at a time and keep the request evidence. Start with a narrow date range, verified location, and verified provider. Confirm working hours first. Then compare an unfiltered provider request with the intended appointment type, operatory, and working-hour source filters. Stop when one added filter changes the result from available to empty.

  1. Capture the empty response and exact request without credentials.
  2. Retrieve matching working-hour records and confirm active coverage in local time.
  3. Check appointment-type assignment and duration against those records.
  4. Check operatory scope and any working-hour source or label filter.
  5. Inspect overlapping appointments and calendar unavailabilities.
  6. Repeat the original request and record whether the same slot appears.

Success means the API returns the expected slot for the intended configuration, not merely that any slot appears somewhere. Keep reminders out of this test unless the booking itself succeeds. If multiple systems may message the same appointment later, use the separate process to assign one reminder owner per message purpose.

What evidence should be sent to support or an integration team?

A useful escalation packet contains the request path, sanitized parameters, response, API version, capture time, relevant IDs, and matching working-hour records. Include whether hours are manual or synced and identify the EHR product. Omit names, contact details, treatment descriptions, and other patient data.

State the expected result precisely: for example, one provider should have one bookable interval at a stated local time for one appointment type and operatory. Attach the observed result and the last known successful test if available. Do not claim a synchronization defect until the records and request prove that the documented inputs all match.

If the slot later becomes an appointment, preserve the original operational source and subsequent action history. That prevents a technical retest or reschedule from being counted as new demand and keeps the troubleshooting record useful without turning it into a patient chart.

Frequently asked questions

Does an open EHR calendar guarantee NexHealth availability?

No. NexHealth evaluates only configured working hours and then applies the request’s provider, location, appointment type, operatory, and date scope before subtracting appointments and unavailabilities. The EHR can look open while no eligible NexHealth working-hour record covers that time.

Can a successful HTTP 200 response still contain no slots?

Yes. NexHealth’s configuration guide shows a successful response with an empty slots array when active availability is missing. Treat transport success and scheduling eligibility as separate checks. Save the response description and next_available_date with the sanitized request.

Why does availability disappear when appointment_type_id is added?

The appointment type narrows the search to working hours associated with that type and supplies the slot duration. If no working-hour record carries that association, NexHealth documents that no slots will return. Verify the NexHealth type ID rather than matching labels by sight.

Should the team create manual working hours to fix an empty response?

Not automatically. First determine whether the location uses manual or synced working hours. NexHealth says synced hours are managed in the EHR, while manual hours are edited through NexHealth. Adding a second source without a clear ownership decision can create overlapping records and misleading results.

References