P PolyAI × Planet DDS · Cloud 9
Integration Reference

Scheduling and intake on Cloud 9 — every branch, every procedure, every published limit.

A field reference for PolyAI voice agents integrating with Planet DDS Cloud 9 Ortho. Built strictly from Planet DDS's own documentation — the Basic Guide and Commonly Used APIs (12.10), the Allowable APIs During Production Hours list, the New Patient Online Scheduling Process, and the 2026 API Pricing schedule. Where the documented API cannot complete a flow, this guide says so plainly, and sets out what we do instead.

XML over HTTP POST · single endpoint 5 use cases mapped 17 of 21 procedures live in-call Costed against 2026 pricing
!

Scope — Cloud 9 Ortho only. This is not Denticon.

Planet DDS ships three products: Cloud 9 (orthodontic PM), Denticon (general-dentistry PM) and Apteryx (imaging). The documentation behind this guide covers Cloud 9 only, and the integration agreement it describes is scoped to “any ortho Cloud 9 Software client.” A general-dentistry DSO running Denticon needs a separate API specification that we have not been provided — none of the procedures below apply to it.

Integration model

One endpoint, ten writes, and two access windows

Cloud 9 is not a FHIR server and shares no surface with Epic, Cerner or AthenaOne. Planet DDS describe their own API as “custom (SOAPish) XML” — a single handler that dispatches on a <Procedure> element inside the request body. Three properties of that design shape the whole integration.

01 One endpoint

Every one of the ~100 operations is an HTTP POST to GetData.ashx. The operation is named in the body, not the path. There is no REST resource model, no HTTP verbs beyond POST, and no status-code semantics — errors come back 200 OK with an <ErrorCode>.

02 Credentials in the body

Auth is a ClientID GUID plus a static UserName / Password, sent in the request body on every call. No OAuth, no bearer tokens, no expiry, no refresh. One credential set per client database.

03 Two access windows

The full API is available 00:00–11:00 UTC. Outside that, Planet DDS publishes a standing allowable-APIs list for production hours, each procedure with its own call interval. Every write these flows need is on it.

The canonical booking sequence

For an established patient, five procedures carry the whole flow. Two of them are the join that Cloud 9 does not make for you.

1 · GetPortalPatientLookup

Resolve caller → PatientGUID. Filter accepts last name, first name or Patient ID — not a phone number. Returns PatientBirthDate for the DOB verifier.

2 · GetPatientRelationshipContactInfo

Per-patient contact rows. This is how the third identity point (phone) is verified once you already hold a patGUID.

3 · GetOnlineReservations

Bookable slots from the office's schedule templates. Capped at a 28-week range; only appointment types flagged Allow Online Scheduling in Setup are returned.

4 · Carry the slot's identifiers

Planet DDS confirms that StartTime, ScheduleView, ScheduleColumn and Minutes all come straight from the chosen reservation — no separate column lookup is needed.

5 · SetAppointment

Writes the appointment. Returns Appointment GUID Added: apptGUID. Rejects past-dated times and slots the template will not accept.

Request shape

Request<!-- POST https://us-ea1-partner.cloud9ortho.com/GetData.ashx --> <?xml version="1.0" encoding="utf-8" ?> <GetDataRequest xmlns="http://schemas.practica.ws/cloud9/partners/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ClientID>[Cloud9 Client GUID]</ClientID> <UserName>[Partner UserName]</UserName> <Password>[Partner Password]</Password> <Procedure>GetPortalPatientLookup</Procedure> <Parameters> <filter>Hernandez</filter> <lookupByPatient>1</lookupByPatient> <pageIndex>1</pageIndex> <pageSize>50</pageSize> </Parameters> </GetDataRequest>

Response shape

Response · success<GetDataResponse xmlns="…/cloud9/partners/"> <ResponseStatus>Success</ResponseStatus> <Records> <Record> <PatientGUID>59D26B3E-…-BD9C03452B86</PatientGUID> <PatientBirthDate>12/30/1999 12:00:00 AM</PatientBirthDate> <PatientMiddleName xsi:nil="true" /> <!-- null --> </Record> </Records> </GetDataResponse>  <!-- errors also return HTTP 200 --> <ResponseStatus>Error</ResponseStatus> <ErrorCode>7</ErrorCode> <ErrorMessage>Not authorized to collect data outside of allowance window.</ErrorMessage>

Surface used by these flows

CapabilityCloud 9 procedure(s)Status
Patient identificationGetPortalPatientLookupName / ID only — no phone
Identity verification (3rd point)GetPatientRelationshipContactInfoSupported
Locate appointmentsGetPatientAppointmentsSupported
Slot availabilityGetOnlineReservations28-week cap · 15s interval
BookSetAppointmentSupported — join confirmed
CancelSetAppointmentStatusCanceledSupported — no reason field
ConfirmSetAppointmentStatusConfirmedSupported
Reschedule— none —No native operation
Create patientSetPatient · SetPersonRelationshipHard DB preconditions
Coverage on file (read)GetInsurancePoliciesForPatientStored record — not eligibility
Real-time eligibility (270/271)— none on Cloud 9 —Denticon-only product
Reverse phone lookup— none —Cache + local index
Payment capture— none —No Set procedure exists
i
Read the status column literally. Every “no native operation” row was verified against the full 100-procedure index in the Planet DDS integration guide, not inferred from absence in a subset.

Where the platform earns its place

Cloud 9's constraints — a closed daytime window, no push events, no phone-indexed lookup, no atomic reschedule — are exactly the constraints that a thin “call the EHR from the turn” integration handles badly. Agent Studio carries three things that make it workable:

A cache tier that is part of the agent

Nightly deltas via GetAppointmentListSince and GetPatientList(ModifiedSince) land in a store the agent reads inside the turn — no live dip needed for identification.

Deterministic branch logic

The cancel-then-book reschedule needs a real failure branch, not a prompt that hopes. Studio steps make the compensating path explicit and testable.

Variants per location

GetLocations returns a per-location TimeZone. Variants re-scope the agent's date maths and hours to the resolved location rather than a single global assumption.

Access model

Two windows — overnight and daytime

Planet DDS put it plainly: “There are two windows for APIs, overnight and daytime.” The full API is available overnight; during the day a published allowable-APIs list applies, each procedure with its own call interval. Which window a procedure sits in determines the whole architecture.

The two windows

UTC
OVERNIGHT — ALL APIs
DAYTIME — ALLOWABLE LIST
00:0006:0012:0018:0024:00
WindowUTCWhat is availableUsed for
Overnight in-window00:00 – 11:00The full API surfaceThe overnight sync — bulk extracts, reference data, the reverse-phone index
Daytime out-of-window · “production hours”11:00 – 24:00Planet DDS's published allowable-APIs list, each at a defined call intervalEverything the agent does live while a caller is on the phone
17 of the 21 procedures in this guide are on the daytime list — including all seven writes. Booking, cancelling, confirming and creating a patient are sanctioned for daytime use as standard. The four that are not are bulk and reference reads that belong in the overnight sync regardless.

Published call intervals

Every allowable procedure carries a frequency, written overnight / daytime in seconds — the minimum interval between calls. These are the real operating constraint; monthly volume rarely binds first.

i
Planet DDS explain the reasoning directly: Cloud 9 is cloud-based, and “there are some restrictions in place to protect all Cloud 9 clients’ performance.” The intervals are shared-tenancy protection, not an arbitrary ceiling — and honouring them is what keeps a practice’s own Cloud 9 responsive while the agent is working.
ProcedureIntervalBearing on the agent
SetAppointment · SetPatient · cancel · confirm5 / 5Every write in these flows. Five seconds is comfortable for a single conversation
GetPortalPatientLookup · GetPatientAppointments · GetPatientRelationshipContactInfo5 / 5Identification and appointment lookup
GetOnlineReservations15 / 15Slot search. Widening a search re-calls this — budget 15s between attempts and fill conversationally
SetPersonRelationship15 / 30Guardian linking. Thirty seconds in daytime — the slowest step in new-patient registration
SetPatientComment · GetInsurancePoliciesForPatient1 / 1Effectively unthrottled
GetNextVisits15 / 800Over 13 minutes between daytime calls — unusable in a live conversation, and not used here
GetIsFamilyPartyList15 / 300Five minutes in daytime. Read it from the overnight sync instead of live
!
The 12-per-minute ceiling — the single biggest open risk on this integration.
Patient identification calls GetPortalPatientLookup once per conversation. At a 5-second interval that is 12 identifications per minute — 720 per hour. If the interval is scoped per client database, that is the hard ceiling for every caller sharing that database, no matter how many locations or phone lines sit behind it.
Planet DDS do not document the scope. Per credential or per partner would be materially different, and the difference decides whether a large DSO on a single database is viable at peak.
ScenarioPeak identifications/minAgainst a 12/min ceiling
Single practice, busy Monday morning~2–4Comfortable
Small group, 5–10 locations, one database~5–8Workable — queues at peak
DSO, 25+ locations, one database15–30+Exceeds the ceiling
DSO, one database per location12/min eachScales cleanly

Intervals are per procedure, so identification does not contend with slot search or booking — each has its own bucket. Identification is the binding one because every conversation needs it. Note too that Planet DDS state the published frequencies are defaults, finalised “once vendor testing has been completed, based on service needs” — so there is a documented route to negotiating them with evidence.

!
Two questions to put to Planet DDS together: is the call interval scoped per client database, per partner, or per credential — and for a multi-location group, is the deployment one database or one per location? The answers decide the largest account size this integration supports without a frequency uplift.

What the overnight sync carries

Four procedures used here sit outside the production-hours list. All four are bulk or reference reads — the kind of data that should be cached in any case.

ProcedureWhy it is synced
GetPatientPhoneReturns every patient's numbers with no phone-side filter. Builds the reverse-phone index that makes caller-ID recognition possible
GetPatientList ModifiedSinceIncremental patient delta for the local index
GetPostalCodesPostal-code GUIDs for registration. If a caller's code is absent, Planet DDS's guidance is to leave the GUID blank and send city/state/zip — so a stale cache degrades gracefully
GetPatientStatuses · GetContactInfoTypesPre-flight assertions for SetPatient: a status coded NEW and a contact type described Home must both exist

GetAppointmentListSince, GetLocations, GetAppointmentTypes, GetScheduleViewList and GetEmployees are all also allowable during production hours, so they are cached for speed rather than necessity — and can be re-read live if a variant needs to refresh mid-day.

Getting access

Daytime access and SET procedures are granted through the Integration Agreement with Planet DDS — a defined contractual step rather than an open-ended approval.

SET procedures are enabled explicitly

Planet DDS's New Patient Online Scheduling Process names SetAppointment and SetPatient as required, plus SetPatientDemographicInfo, SetPerson, SetPersonDemographicInfo and SetPersonRelationship. These must be enabled before testing, not just before production.

Frequencies are set after testing

The published intervals are defaults; Planet DDS states they are finalised “once vendor testing has been completed, based on service needs.” There is room to discuss them with evidence.

Anything off-list needs approval

Procedures outside the allowable list “must go through an approval process and are not guaranteed.” None of the flows in this guide depend on one.

Version drift is real

The allowable list is published against the 12.5 release; the API guide is 12.10. Request the current list at contract time and re-check it each release.

i
Planet DDS closes the allowable-APIs document with a plain warning: any negative impact on their clients, or misuse of the APIs, can lead to termination without notice. Respecting the published intervals is not merely good practice — the agent's throttling is built to honour them.
Scope & clinical line

Why intake and coverage are in scope — and where the clinical line sits

The agent performs administrative patient-access work. It does not assess symptoms, judge urgency, or decide what care a patient needs — and it never adjudicates coverage.

1 · The administrative / clinical line

Every procedure this guide uses is scheduling, demographic or financial. Cloud 9's clinical surface — treatment cards, charting, imaging — is not touched by any flow here. That is a deliberate boundary, and it happens to be easy to hold in Cloud 9 because the documented API exposes very little clinical data in the first place.

The agent doesThe agent does not
Resolve who is calling against existing recordsInterpret a clinical complaint or rank its urgency
Map a stated reason to a configured appointment typeDecide what treatment the patient needs
Read the coverage already on file and report itAdjudicate, approve or deny coverage
Offer slots the practice has flagged bookableCreate availability, override templates or double-book
Write appointments, cancellations and confirmationsWrite clinical notes, charting or treatment plans

2 · The Emergency Safety-Net — the controlling guardrail

Every booking flow is fronted by a Safety-Net step that screens for emergency cues before anything else happens. The cue set is authored and approved by the customer's clinical leadership, not by PolyAI, and is deliberately tuned to over-escalate.

!
An orthodontic practice's cue list is its own. Facial trauma, uncontrolled bleeding, airway compromise and swelling are the categories customers typically include — but the operative list must come from the practice in writing, and this guide does not supply one.

On a red flag the agent stops, gives the customer-approved emergency instruction, and transfers to a human. It does not continue to booking, and it does not record a clinical impression.

3 · Coverage — report, never adjudicate

This distinction matters more in Cloud 9 than in the other EHRs, because Cloud 9 gives you data that looks like an eligibility answer and is not one.

What GetInsurancePoliciesForPatient is

The practice's stored record of the patient's policy: carrier, billing centre, policy and group number, subscriber, and the Emdeon payer ID. Written by staff, accurate as of whenever they last touched it.

What GetPatientInsurancePolicies adds

Benefit fields including pipIndividualOrthoMax, pipLifetimeMax and pipIndividualOrthoMaxRemaining. These are Cloud 9's own running totals — useful, and not a payer response.

What neither is

There is no 270/271 transaction anywhere in the Cloud 9 API. No procedure contacts a payer. SetAppointmentInsuranceVerified ticks a checkbox on the appointment bubble — it verifies nothing and calls nobody.

!
If the customer expects real-time verification, it requires the same clearinghouse seam used in the Epic / Cerner / Athena guides (pVerify or equivalent) running alongside Cloud 9, keyed off the stored payer ID.
Reporting a benefit figure is administrative. Deciding coverage is an adverse determination that AI is increasingly barred from making. The agent quotes what is on file, attributes it as on-file information, and never states that a service is or is not covered.

4 · Minors, guardians and the responsible party

Orthodontics skews heavily paediatric, so the caller is frequently not the patient. Cloud 9 models this well and the agent should use it rather than improvising.

NeedProcedureNote
Who may act for this patientGetPatientRelationshipContactInfoReturns Relationship, FullName, persGUID per contact row
Who is financially responsibleGetResponsiblePartiesForPatientOnly relationships flagged financially responsible
Family groupingGetIsFamilyPartyListResponsible parties flagged Is Family
Link a new relationshipSetPersonRelationshipA patient must have at least one responsible party. The FRP flag cannot be turned off via API.
i
Verify the caller against the relationship rows before disclosing anything. A name that does not appear as a relationship on the patient is not authorised by default — route to staff.

5 · Roles, ownership & sign-off

ArtefactOwnerSign-off
Emergency cue list & escalation scriptCustomer clinical leadershipWritten approval before go-live
Appointment-type mapping (reason → type)Customer practice operationsReviewed per location
Which procedures are whitelisted for daytimePlanet DDS integrationsBlocking dependency
Client authorisation form per databaseCustomerRequired before credentials are issued
MNDA + Integration AgreementPolyAI ↔ Planet DDSPrecedes any documentation or sandbox
Coverage-disclosure languageCustomer + PolyAIMust not imply adjudication
Call flows

Branch logic, fallbacks, and the procedure at every node

Pick a flow, then click any node to see what the agent says, what it captures, or the exact Cloud 9 procedure it calls with per-field provenance. Purple nodes are shared sub-flows — click to drill in.

Data capture

Handling the hard-to-capture data points

Each item below is captured by voice under adverse conditions and then used as a match key, a security verifier or a write payload. Strategy, validation and fallback for each.

API reference

Every procedure, grouped by the use case that calls it

Expand a use case to see the procedures it uses; expand a procedure for its parameters, its returns, and where each field comes from in the conversation. Nothing here is aspirational — every procedure listed is documented in the Planet DDS integration guide, and every field is traced to the moment in the call that produces it.

How to read this page

Three terms carry most of the meaning, and they are worth two minutes — they are the vocabulary this integration is scoped, approved and supported in.

Procedure

Cloud 9 exposes its API as a set of named procedures rather than REST endpoints — the operation is named inside the request body, not in the address. Around a hundred exist across reads and writes; this guide uses twenty-one of them — seventeen live during the working day, four from the overnight sync.

Why we use the wordIt is Planet DDS's own term, and the procedure is the unit they approve, rate-limit and support. Speaking their vocabulary keeps every conversation — technical and commercial — unambiguous.
What it means for the practiceScope is discussed in concrete, countable units rather than abstractions. When we say a use case needs six procedures, that is exactly what gets requested and exactly what runs.
Daytime

Planet DDS grants standard API access between 00:00 and 11:00 UTC, and publishes a standing list of procedures that are additionally allowable during production hours — the practice's working day. Each carries a call interval in seconds, shown as its own badge.

Why this is the good news17 of the 21 procedures this guide uses are already on that list — including every write. Booking, cancelling, confirming and registering a patient are all sanctioned for daytime use as standard, at intervals of five seconds. This is a documented, standing allowance, not a bespoke negotiation.
What it means for the practiceThe agent identifies callers and books real appointments into real slots while the caller is on the phone, with no copy of your patient data held at rest. Daytime access and SET procedures are granted through the Integration Agreement, so it is a defined contractual step rather than an open question. The one thing to size carefully is the identification interval — see the Access Model tab.
Overnight

Four small reference lists sit outside the daytime list — patient statuses, contact-info types and postal codes. PolyAI reads them inside the overnight window and caches them. They are vocabularies, not patient data.

Why PolyAI builds it this wayThere is no live option for these, and none is needed: they are small, change rarely, and carry no patient information. Two of them — a status coded NEW and a contact type described Home — are the pre-flight assertions that decide whether new-patient registration can work at all.
What it means for the practiceNo patient data is held at rest. Patient records are read live during the call and not retained, so the integration keeps no standing copy of your patient list. Locations, appointment types, schedule views and providers are cached too, purely for speed — all are daytime-allowable and can be refreshed live.
Every procedure below is labelled one way or the other, and you can filter by either. Nothing in these flows falls outside Planet DDS's published allowances — the live work is sanctioned for production hours, and everything else is cached from the standard window.

The other badges

BadgeMeaning
Cloud 9The platform serving the call. Every procedure in these flows is Cloud 9's own — this integration introduces no third-party dependency.
GET  SETPlanet DDS's own division of the API. GET reads; SET writes. There are around ninety GET procedures and exactly ten SET procedures — so the writes are worth knowing individually, and this guide uses seven of them.
GET · ref GET · syncReads that serve the overnight synchronisation rather than the live call — reference lists and incremental deltas respectively. GET · bulk denotes a full extract.
1–3×Expected calls per conversation, with conditional branches already weighted. This is what the Usage Estimator multiplies by your volumes.
Platform FeePlanet DDS charges an initial and a monthly recurring integration fee. No per-call pricing is published, so call volume affects approval and rate limits rather than a per-transaction bill — which is why this guide estimates procedure volume rather than cost.
VerifyBehaviour the Planet DDS documentation does not settle. We have flagged it rather than assumed it, and it sits on the list to confirm with Planet DDS.
GapA capability confirmed absent from the documented API, with the workaround stated wherever one exists.
Usage estimator

Estimate call volume from projected conversations

Planet DDS publishes tiered bundle pricing with a generous included call allowance, so this estimates both procedure volume and cost — and shows how much of the included allowance the agent actually consumes.

Monthly conversation volume

Enter expected conversations per month for each use case.

Number of offices

Drives the Planet DDS pricing tier and the per-office call allowance.

12
Containment rate

Share of conversations reaching the end of the flow. Non-contained calls still consume the early lookups.

70%

Estimated procedure calls per month

How the estimator works

Each use case has a per-conversation call profile drawn from the flows in this guide. Conditional calls are weighted by how often that branch is expected to fire; fallback calls are weighted lower still. Volume is split into calls that run live during production hours and calls served from the overnight sync, so the two can be quoted separately.

Cost follows Planet DDS's 2026 API Pricing: the flows here need the Patient & Clinical and Appointments bundles, priced per office per month on a five-tier scale, with 130,000 calls included per office per bundle and additional calls at $0.0025. Cloud 9 counts as a single product, so the $10,000 implementation fee applies once.

!
Monthly volume is rarely the binding constraint — the per-procedure call interval is. Planet DDS publishes these (5 seconds for SetAppointment, 15 for GetOnlineReservations) but does not state whether the interval is scoped per client database or per partner. Take the live figure and your expected peak concurrent calls per office to Planet DDS before committing to a launch volume.
Authentication

Static credentials, per client database

There is no OAuth flow, no token endpoint and no expiry. Every request carries the full credential set in its body — which changes how secrets, rotation and multi-tenancy have to be handled.

The credential triple

Planet DDS describe it as “basic authentication — username, password, and Client ID.” Note that despite the name, the credentials travel as elements in the XML body, not in an HTTP Authorization header.

ElementScopeIssued by
ClientIDOne GUID per client databasePlanet DDS, after the client signs an authorisation form
UserNameStatic, per integrationPlanet DDS
PasswordStatic, per integrationPlanet DDS
VendorUserNamePer write — stamped as the actor on the recordPolyAI (max 25 chars)
!
Credentials are static and non-expiring. There is no refresh mechanism and no documented rotation procedure — rotation is a support request. Store them as secrets and never log a request body.

Built for multi-location groups

Cloud 9 models a group practice as separate databases, each with its own Client ID. Planet DDS sets the expectation directly: “The vendor or third-party must have the ability to update any number of URLs (databases) for each client.” PolyAI is built for exactly that shape.

i
Identifiers are scoped to their database. Planet DDS notes that GUIDs “can be and sometimes purposefully are shared across multiple databases,” so we key every cached record on (ClientID, GUID) rather than the GUID alone. It is a small design decision made once, and it is what lets a multi-location DSO run on one agent without records from two offices ever being confused for each other.

The endpoint hostname is per-client too — us-ea1-partner is one region — and Planet DDS notes that calling the wrong endpoint for a client returns “BAD RESPONSE: HTTP/1.1 500 Server Error.” We treat the base URL as per-tenant configuration rather than a constant, so adding a location is a config change, not a code change.

Environments

Testing (sandbox)Production
Endpointhttps://us-ea1-partnertest.cloud9ortho.com/GetData.ashxhttps://us-ea1-partner.cloud9ortho.com/GetData.ashx
Availability24/7 open access, confirmed by Planet DDSOvernight: full API · Daytime: allowable list
ScopeOne endpoint, one sandbox, one ClientIDPer-client ClientID; multiple databases
ExpiryInaccessible after 3 months idle; deactivated at 6 months (reactivation fee)
i
The sandbox is 24/7 but production is not. Plan against production hours, not sandbox hours. The sandbox is unrestricted; production applies the allowable-APIs list and its call intervals. Build the throttling in from the start so testing exercises the behaviour production will.

From integration request to live agent

MNDA executed

Required before any documentation changes hands — for each individual party including subcontractors.

Integration Agreement executed

Required before entering a testing state, receiving a sandbox, or touching confidential data. Designates the integration type. Initial and monthly recurring fees attach here.

Sandbox opened · alpha

One endpoint, one ClientID. Vendor is expected to have a working integration within 6 months; an extension of 3–6 months needs written approval.

SET procedures enabled

Planet DDS enables the write procedures against the Integration Agreement. SetAppointment and SetPatient are named as required, and must be live before testing — not just before production.

Demo to Cloud 9

Vendor presents to Planet DDS before any production release. The service must be approved to proceed.

Beta

A small number of mutual clients who have authorised the service, in live production. Target duration ~1 month.

Live

After beta sign-off the vendor may sell to any ortho Cloud 9 client. Each client database still needs its own signed authorisation form before credentials are issued.

Agent Studio

Wiring Cloud 9 into PolyAI Agent Studio

Cloud 9's shape — XML bodies, credentials per call, a closed daytime window, no push events — means the integration layer does real work. This is where that work lives.

Functions, not raw calls

Each Cloud 9 procedure is wrapped in an Agent Studio function that owns the XML envelope, injects the credential triple from secrets, parses <Records> into typed output, and — importantly — maps ErrorCode to a branchable outcome rather than an exception.

ErrorCodeAgent behaviour
0 unknown errorRetry once, then handoff
1 invalid credentialsDo not retry. Alert; handoff every call until resolved
2/3/4/5 bad inputRe-capture the offending field, then retry once
7 outside allowance windowShould not occur for the procedures used here — alert as config drift and fall back to cache for reads
8 rate limitedThe published interval was breached. Back off for the stated seconds; serve from cache where possible
9/10 not allowable / not authorisedConfiguration matter — alert and hand off. Never retry in a loop
16 procedure validation failureSurface the specific message; re-capture if it names a field
Because errors arrive as 200 OK, the wrapper must inspect <ResponseStatus> on every response. An HTTP-status-only check will treat every failure as a success and return an empty record set.

Config & secrets

ItemWhere
ClientID, UserName, PasswordProject secrets, per environment
Base endpoint URLConfig variable — per tenant, not global
VendorUserNameConfig variable (≤25 chars)
Default locationGUID, providerGUIDConfig page, per location variant
Schedule view / column GUID mapRefreshed by the nightly sync
Reason → appointment-type mappingConfig page, customer-owned

Variants per location

GetLocations returns TimeZone per location — Cloud 9 expects you to know it, and returns datetime values in the plain 12/30/1999 12:00:00 AM format with no offset attached.

!
Every datetime in this API is offset-free. Resolving the location before interpreting “tomorrow at 3” is not an optimisation — it is required for correctness in any multi-location deployment.

Variants re-scope: greeting and practice name, the location's timezone for all date maths, default provider and schedule view, and the bookable appointment-type subset.

The sync job

A small scheduled job running inside the overnight window. Deliberately modest: patient records are read live and not retained, so this carries reference data only.

Reference vocabularies

Patient statuses, contact-info types and postal codes — not on the daytime list, so they must be read in-window. Small, slow-changing, no patient data.

Deterministic patient matcher

Not a sync task but the function it feeds: a Python step that normalises the captured surname and DOB, exact-matches DOB against PatientBirthDate across the candidates, and fuzzy-matches the name above a set threshold. Code, not an LLM judge — this decision gates PHI disclosure and must be deterministic and auditable. An LLM is used only to normalise ASR variants before the comparison.

Reference data

Locations, appointment types, schedule views and columns, patient statuses, contact-info types, SMS carriers.

Pre-flight assertions

Assert a NEW patient status and a Home contact-info type exist. Surfacing these at deploy time turns what would be a quiet registration failure into a one-line config request.

Interval-aware throttling

Built alongside the sync: a per-procedure limiter honouring Planet DDS’s published call intervals so the agent never trips error 8.

Gaps & open questions

What we verified — and what still needs confirming

Everything here was checked against the full procedure index of the 12.10 C9 release guide. Nothing on this page is an assumption of absence — each is a confirmed absence, or a question the document leaves genuinely open.

Deliberately out of scope

These are supported by the API but excluded from the flows in this guide.

CapabilityProcedureWhy excluded
Financial balances & agingGetResponsiblePartyBalance, GetAgingReportDataReading a balance is feasible, but no payment can be taken — quoting a balance with no way to settle it creates a worse call, not a better one.
Contract / payment plan detailGetContracts, GetInsuranceContractsSame reason. Belongs to a treatment-coordinator conversation, not an automated one.
Recall & continuing careGetRecallListByDate, GetPatientsContinuingCareGenuinely useful for outbound campaigns — out of scope for the five inbound use cases here.
No-show & dismissed listsGetNoShowList, GetLastDismissedAppointmentsOutbound reactivation, not inbound handling.
“Sooner if possible” waitlistGetSoonerIfPossibleAppointmentsRead-only. The flag can be read but not set, so the agent cannot add a caller to the waitlist.
PolyAI × Planet DDS Cloud 9 · Built from Basic Guide and Commonly Used APIs, 12.10 C9 Release (October 2025).
Procedure behaviour is as documented by Planet DDS and not yet verified against a live sandbox. Items marked Verify require confirmation from cloud9.integrations@planetdds.com.