Embed booking and intake, read availability
Show the clinic's booking page, interest form or registration inside your site, or build your own widget that reads services and open times from the browser.
What the clinic sends us
Up to five website origins, exactly as the browser sees them: https://www.yourclinic.com, https://yourclinic.com (a different origin from the www one), https://book.yourclinic.com.
https://only. Scheme and host only: no path, no port, no wildcard, no IP address, nolocalhost.- A staging site counts as one of the five, and it must also be served over https.
If an address is wrong or missing, the embed shows "This page can't be shown here" with a link that opens the page in a new tab. Nothing breaks for patients.
Embedding a page
<div data-moonshot-embed="https://<clinic>.moonshotehr.com/embed/?to=/book/"></div>
<script src="https://<clinic>.moonshotehr.com/embed/embed.js" async></script>
| Page | to= |
|---|---|
| Booking (all services) | /book/ |
| One booking link the clinic set up | /book/<link-name> |
| Interest form | /intake/ |
| Registration | /intake/register/ |
- Memberships are linked to, never embedded: sign-up signs the patient in and takes payment. See Membership join links.
- Tracking parameters carry through:
to=/book/?utm_source=website&utm_campaign=fall. - Optional attributes:
data-moonshot-title(the frame's accessible name) anddata-moonshot-min-height(starting height, default 640; the frame then fits the page). - Payment and sign-in steps open in a new tab; no card field is ever shown inside the embed.
- If your site sends a Content-Security-Policy, allow the clinic address in
frame-srcandscript-src. - A plain
<iframe>without the loader works in Chrome, Edge and Safari; Firefox visitors get the "open in a new tab" link instead.
Reading availability from the browser
Once the origins are on file, JavaScript on those sites may call the read API v1 (/api/v1/catalog, /api/v1/availability, /api/v1/availability/summary) with the clinic's identifier in X-Tenant-Slug. GET only, never with credentials: 'include'. That API is the supported contract for reading from a website.
const res = await fetch('https://api.moonshotehr.com/api/v1/catalog', {
headers: { 'X-Tenant-Slug': '<clinic>' },
});
const { data } = await res.json();
Booking itself is not available from your site's JavaScript: send the visitor to the embedded or linked booking page, which keeps identity, payment and consent checks in one place. Cache the services list; do not poll.