> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thoughtly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Calendly integration

> Connect Calendly to Thoughtly so voice agents can check available times, book event types on a caller's behalf, and send confirmation links during the call.

export const IntegrationPage = ({actions, triggers, name, domain, logoOverride}) => {
  const logoOverrides = {
    acuity: 'https://cdn.thoughtly.com/integrations/acuity_scheduling.svg',
    acuityscheduling: 'https://cdn.thoughtly.com/integrations/acuity_scheduling.svg',
    'cal.com': 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    calcom: 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    cal: 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    'fence flow': 'https://cdn.thought.ly/integrations/fence-flow.png',
    fenceflow: 'https://cdn.thought.ly/integrations/fence-flow.png',
    gohighlevel: 'https://cdn.thought.ly/integrations/highlevel.png',
    highlevel: 'https://cdn.thought.ly/integrations/highlevel.png',
    hubspot: 'https://cdn.thought.ly/integrations/hubspot.png',
    keap: 'https://cdn.thoughtly.com/integrations/keap.svg',
    mindbody: 'https://cdn.thoughtly.com/integrations/mindbody.svg',
    pipedrive: 'https://cdn.thoughtly.com/integrations/pipedrive.svg',
    salesforce: 'https://cdn.thoughtly.com/integrations/salesforce.svg',
    slack: 'https://cdn.thoughtly.com/integrations/slack.svg',
    smartsheet: 'https://cdn.thoughtly.com/integrations/smartsheet.svg',
    trello: 'https://cdn.thoughtly.com/integrations/trello.svg',
    zendesk: 'https://cdn.thoughtly.com/integrations/zendesk.svg',
    zoho: 'https://cdn.thoughtly.com/integrations/zoho.svg',
    zoom: 'https://cdn.thoughtly.com/integrations/zoom.svg',
    gmail: 'https://cdn.thoughtly.com/integrations/google-mail.png'
  };
  const normalizeKey = value => (value || '').toString().trim().toLowerCase();
  const normalizeHost = value => {
    if (!value) {
      return '';
    }
    const cleaned = value.replace(/^https?:\/\//, '').replace(/^[^@]+@/, '');
    return cleaned.split(/[/?#]/)[0];
  };
  const getLogoSrc = ({name: logoName, domain: logoDomain, logoOverride}) => {
    if (logoOverride) {
      return logoOverride;
    }
    const nameKey = normalizeKey(logoName);
    const host = normalizeHost(logoDomain);
    const hostKey = normalizeKey(host);
    const hostBase = hostKey.split('.').slice(-2, -1)[0] || '';
    return logoOverrides[nameKey] || logoOverrides[nameKey.replace(/\s+/g, '')] || logoOverrides[hostKey] || logoOverrides[hostBase] || (logoDomain ? `https://logo.clearbit.com/${logoDomain}` : undefined);
  };
  return <div>
		<div className="flex flex-row items-center h-10 pb-4">
			<img src={getLogoSrc({
    name,
    domain,
    logoOverride
  })} className="w-5 rounded-md mr-2 h-5" />
			<div className="text-xl">
				Integrate with <a href={`https://${domain}`} target={"_blank"}><span className="font-bold">{name}</span></a>
			</div>
		</div>

		By integrating Thoughtly with {name}, you can automate tasks and workflows before, during, and after calls. To integrate with {name}, head to the <a href="https://app.thoughtly.com/integration" target="_blank">Integrations</a> page and follow the instructions.

		{triggers && <div>
				<hr />
				<h3>Triggers</h3>

				Triggers are available via <a href="/automations/triggers">Automations</a>. You can use them to start your Automations, such as for initiating a call or sending an SMS.

				{triggers.map(trigger => <div className="text-sm">
						<h4 className="text-gray-600 text-md">{trigger.name}</h4>

						{trigger.description}
					</div>)}
			</div>}

		{actions && actions.length > 0 && <div>
				<hr />
				<h3>Actions</h3>

				Actions are available both via <a href="/agents/nodes">Mid-Call Actions</a> and <a href="/automations/actions">Automations</a>. You can give your Voice Agents access to these Actions so they can perform tasks in {name} during a call, or use them in Automations to automate tasks before and after calls.

				{actions.map((action, i) => <div key={i} className="text-sm">
						<h4 className={`text-gray-600 ${action.deprecated ? 'line-through text-red-500' : ''}`}>
							<span className="text-gray-600">{action.name}</span>
							{action.deprecated && <span className="ml-3 text-xs">(Deprecated)</span>}
						</h4>
						<p className={action.deprecated ? 'text-gray-400' : ''}>
							{action.description}
						</p>
					</div>)}
			</div>}
	</div>;
};

***

<IntegrationPage
  name="Calendly"
  domain="calendly.com"
  actions={[
    {
        "name": "Get Event Type Availability",
        "description": "Returns availability for a given event type.",
    },
    {
        "name": "Schedule Event with Reference",
        "description": "Schedules an event with node reference support for agent contexts. Automatically resolves interview IDs from interview response IDs when used in agent workflows.",
    },
]}
/>

## Timezone handling

The timezone field is optional for all Calendly actions. When not specified, the system uses the following fallback order:

1. **Timezone input** — If you provide a valid timezone in the action configuration
2. **Agent timezone** — The timezone configured in your agent's advanced settings
3. **Default timezone** — Falls back to `America/New_York` if no timezone is available

This allows you to use variables for timezone selection, letting callers choose their preferred timezone during the call. Available times are automatically formatted with the resolved timezone for accurate scheduling.
