Skip to content

How to Embed Scheduling into Existing Software: Integration Guide

Add an existing scheduler to a website or application with an example embed, a fallback link and a test plan for confirmations, mobile use and handoffs.

A compact embedded calendar is compared with a custom booking workflow linked to staff and rules.

Start with the scheduling workflow the existing software supports

To embed scheduling into existing software, choose the provider and event type, add its supported booking interface, and test the complete journey into the calendar and the team’s working system. The embed is one part of the integration. Availability, confirmation, cancellation and ownership still need to be configured in the scheduling platform.

First decide whether visitors need a public booking page or a workflow connected to an account in your application. A public link can be suitable for an introductory appointment. An appointment linked to a private client record needs an appropriate server-side identity and authorization design; a public URL parameter should not establish ownership of that record.

If you have not chosen the approach, compare scheduling embeds and custom booking systems before building the integration.

Choose an embedded calendar or a direct booking link

Scheduling interface choices
OptionUseful whenWhat to test
Direct booking linkA supported provider page is sufficient for the customer journey.The destination, return path, mobile experience and accurate event information.
Inline embedCustomers should choose a time within the website or application.Container size, keyboard access, scrolling and failure fallback.
Custom integrationThe application needs supported workflow actions beyond presenting the scheduler.Provider API capabilities, identity, permissions, error handling and ongoing ownership.

Calendly’s embed documentation describes loading its widget script and initialising an inline calendar with a scheduling URL and parent element. The example below uses that documented interface. Review the provider’s current terms and options when adapting it.

Confirm who owns the scheduling account, connected calendar and notifications. A staff member leaving should not make the booking route impossible to administer. Use the provider’s supported administration and connection methods rather than sharing a personal password.

Example: load a calendar on request and keep a direct link available

This example is for a standalone test page. Enter a public Calendly event URL from an account you control. It requests the external widget only after the button is pressed and leaves a direct link available if the embedded interface fails. It does not create an appointment by itself or verify that a booking was completed.

HTML and JavaScript

<label for="booking-url">Your public Calendly event URL</label>
<input id="booking-url" type="url" required
       placeholder="https://calendly.com/your-team/your-event">
<button id="load-booking" type="button">Load booking calendar</button>
<p id="booking-status" role="status" aria-live="polite"></p>
<p><a id="booking-fallback" hidden target="_blank" rel="noopener noreferrer">Open the booking page</a></p>
<div id="booking-widget" style="min-width:0;height:720px"></div>
<script>
const input = document.getElementById('booking-url');
const button = document.getElementById('load-booking');
const status = document.getElementById('booking-status');
const fallback = document.getElementById('booking-fallback');
const container = document.getElementById('booking-widget');
let widgetScript;
function loadWidgetScript() {
  if (window.Calendly) return Promise.resolve();
  if (!widgetScript) widgetScript = new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = 'https://assets.calendly.com/assets/external/widget.js';
    script.onload = resolve;
    script.onerror = () => { script.remove(); widgetScript = undefined; reject(new Error('load')); };
    document.head.append(script);
  });
  return widgetScript;
}
button.addEventListener('click', async () => {
  if (!input.reportValidity()) return;
  const url = new URL(input.value);
  if (url.protocol !== 'https:' || url.hostname !== 'calendly.com' ||
      url.username || url.password || url.port ||
      url.pathname.split('/').filter(Boolean).length < 2) {
    status.textContent = 'Enter your public HTTPS Calendly event URL.';
    return;
  }
  fallback.href = url.href;
  fallback.hidden = false;
  button.disabled = true;
  status.textContent = 'Loading the calendar. The direct booking link is also available.';
  try {
    await loadWidgetScript();
    container.replaceChildren();
    window.Calendly.initInlineWidget({ url: url.href, parentElement: container });
    status.textContent = 'Calendar requested. If it does not appear, use the direct booking link.';
  } catch {
    status.textContent = 'The calendar could not load. Use the direct booking link.';
  } finally {
    button.disabled = false;
  }
});
</script>

For a production page, configure the approved event URL in the application rather than asking customers to supply it. Move inline script and styles into the project’s normal files where required by its content-security policy. In a single-page application, integrate loading and cleanup with the view lifecycle so repeated navigation does not accumulate widgets or event handlers.

A deliberate load button does not replace a consent policy. Review the external requests, cookies and information passed to the provider, then connect the integration to the site’s applicable privacy controls. Keep private records and API credentials out of the browser example.

Open the working scheduling embed demo. It uses the code above. Bring your own public event URL; there is no preconfigured appointment. Loading is user-initiated, and a direct link remains available if the widget fails.

Verification scope: the sample’s loading, URL validation, retry, replacement and fallback behavior were checked with a mocked provider script. We did not have a configured organiser account, so availability, booking confirmation, cancellation, timezone behavior and webhook delivery are not independently verified here.

Distinguish interface activity from confirmed bookings

A loaded calendar shows only that the interface was requested. An interface event or a thank-you message can support user feedback, but should not alone authorise an account change, release a paid service or mark an internal task complete. Define the authoritative booking record and reconcile any application state with it.

Calendly documents APIs and webhook integration for connecting scheduling data to other systems. Verify the capabilities and access available to your account. When using server notifications, validate them using the provider’s documented method, handle repeated deliveries and define what happens after cancellation or rescheduling.

Booking handoff decisions
QuestionDecision to record
Where is the booking authoritative?The scheduling provider or another explicitly defined system of record.
How does it reach the team?Calendar, inbox or CRM destination and the person responsible.
How are changes handled?Rules for cancellation, reassignment and rescheduling.
How is success measured?Confirmed bookings, attended appointments and qualified enquiries as separate outcomes.

Test the whole journey on the devices customers use

  1. Open the page on a narrow phone viewport and with keyboard navigation.
  2. Confirm that the intended service, duration, host and time zone are shown.
  3. Complete an authorised test booking and verify the provider record, calendar and notification.
  4. Reschedule and cancel the test appointment, checking downstream records.
  5. Block the widget script in a test environment and verify the direct-link fallback.
  6. Navigate away and back in an application and check for duplicate widgets or handlers.
  7. Confirm that the business can administer the event and recover from a disconnected calendar.

Record observed outcomes and unresolved issues rather than marking every test complete because the first screen appears. The code example demonstrates loading and fallback behaviour; a real booking test still needs your configured provider account and calendar. Avoid placing live customer bookings while testing.

For teams, check the staff eligibility and conflict test matrix as part of the same acceptance review.

Questions about embedding scheduling

Do I need API access for a basic embed?

A supported public embed can often display an existing event without private API credentials. Additional application actions or data synchronisation may require provider-supported API access and server-side work.

What if the embedded calendar fails?

Provide a clearly labelled direct booking link and a normal contact route. A link helps when the embed fails, while a contact route also helps during a provider outage.

Can an embed guarantee that bookings will not conflict?

No. Correct availability, resource rules and calendar connections still need configuration and testing in the scheduling system.

Has this example completed a real appointment?

The example is an integration pattern to adapt to your account. Its loading and fallback behaviour can be tested independently; booking, notifications and calendar synchronisation must be verified against your configured event.

← Back to resources

Keep exploring

Related reading