Skip to content

Calendly ​

Reads your event types and scheduled events, and can cancel one.

The Calendly node reads your event types and your scheduled events, and can cancel an event. Its most common use is a reply that offers a booking slot: list your event types, then paste {{ data.<step>.schedulingUrl }} into a Compose step.

It works with one Calendly account through a personal access token stored once in Connections. See Calendly to create the connection.

At a glance ​

  • Type: calendly.api · version 1
  • Category: Data
  • Kind: Step — one stage of a run
  • Effect: Writes outside (external_write) — writes outside Mankomail; described instead of performed during a test run
  • Needs a carrier email: No
  • Connection: Calendly
  • Inputs: main
  • Outputs: main

Connection ​

This node needs a Calendly connection.

Parameters ​

connection ​

Calendly connection — The Calendly connection to use. Create it once in Connections; its key never appears in the workflow.

  • Type: Connection (credential)
  • Required: Yes
  • Default: "" (empty)

action ​

Action

  • Type: One choice (options)
  • Required: Yes
  • Default: eventTypes
  • Options:
    • eventTypes — List my event types: With their booking link, ready to paste into a reply.
    • events — List scheduled events: Filterable by period, status and event type.
    • event — Get one scheduled event: Its details, and its invitees.
    • cancel — Cancel a scheduled event: Calendly notifies the invitee — that is its behaviour, not an option.
    • me — Get my account: Name, address, time zone and booking page.

eventType ​

Event type — Optional when listing events: left empty, every event type is included.

  • Type: Remote resource (resourceLocator)
  • Required: No
  • Ways to choose: pick from a list, type an ID, paste a URL (calendly.eventType)
  • Listed with the connection in: connection
  • Shown when: action is one of eventTypes, events

eventUri ​

Scheduled event — The event URI (https://api.calendly.com/scheduled_events/…), as the list returns it in data.

  • Type: Text (string)
  • Required: Yes
  • Default: "" (empty)
  • 500 characters at most
  • Example: {{ data.api_1.events[0].uri }}
  • Shown when: action is one of event, cancel
  • Expressions: {{ }} accepted

withInvitees ​

Include invitees — One more request: name, email and the questionnaire answers.

  • Type: Yes / no (boolean)
  • Required: No
  • Default: true
  • Shown when: action is event

status ​

Status

  • Type: One choice (options)
  • Required: No
  • Default: active
  • Options:
    • any — Any
    • active — Active
    • canceled — Canceled
  • Shown when: action is events

minStartTime ​

From — An ISO 8601 instant (2026-09-22T00:00:00Z). Empty = no bound.

  • Type: Text (string)
  • Required: No
  • Default: "" (empty)
  • 40 characters at most
  • Shown when: action is events
  • Expressions: {{ }} accepted

maxStartTime ​

To

  • Type: Text (string)
  • Required: No
  • Default: "" (empty)
  • 40 characters at most
  • Shown when: action is events
  • Expressions: {{ }} accepted

limit ​

Maximum count

  • Type: Number (number)
  • Required: No
  • Default: 20
  • Whole number, from 1 to 100
  • Shown when: action is one of eventTypes, events

reason ​

Cancellation reason — Sent to the invitee by Calendly. Accepts {{ }} expressions.

  • Type: Long text (text)
  • Required: No
  • Default: "" (empty)
  • 500 characters at most
  • Shown when: action is cancel
  • Expressions: {{ }} accepted

Outputs ​

  • main — Taken once the Calendly call has succeeded, whatever the action. An error answer from Calendly fails the step instead.

Data produced ​

What this node adds to the run data, and how to read it in an expression. <step> stands for the step key: the node name turned into an identifier (see Data and expressions).

  • {{ data.<step>.schedulingUrl }} — string. List my event types only: the booking link of the first event type returned (or of the chosen event type). Empty when none is found.
  • {{ data.<step>.eventTypes }} — array of { uri, name, durationMinutes, schedulingUrl, description }. List my event types only: the active event types of the account, sorted by name. uri is the Calendly URI of the event type, schedulingUrl its booking link, description its plain-text description.
  • {{ data.<step>.events }} — array of { uri, name, status, startTime, endTime, eventTypeUri, location }. List scheduled events only: the scheduled events, earliest first. uri is what Get one scheduled event and Cancel a scheduled event expect, status is active or canceled, location is the location object exactly as Calendly returns it.
  • {{ data.<step>.events.0.uri }} — string. List scheduled events only: the URI of the first event returned.
  • {{ data.<step>.count }} — number. List my event types and List scheduled events: the number of items returned.
  • {{ data.<step>.truncated }} — boolean. List my event types and List scheduled events: true when more items existed than Maximum count allowed.
  • {{ data.<step>.event }} — { uri, name, status, startTime, endTime, eventTypeUri, location }. Get one scheduled event only: the event read.
  • {{ data.<step>.invitees }} — array of { uri, name, email, status, timeZone, cancelUrl, rescheduleUrl }. Get one scheduled event only: the invitees of the event, when Include invitees is on (empty otherwise). cancelUrl and rescheduleUrl are the invitee's own links.
  • {{ data.<step>.inviteeName }} — string. Get one scheduled event only: the name of the first invitee, empty when there is none.
  • {{ data.<step>.inviteeEmail }} — string. Get one scheduled event only: the email address of the first invitee, empty when there is none.
  • {{ data.<step>.user }} — { uri, name, email, schedulingUrl, timeZone, organization }. Get my account only: the account of the connection. schedulingUrl is its booking page, organization the URI of its current organisation.
  • {{ data.<step>.cancelled }} — boolean. Cancel a scheduled event only: true when the cancellation was sent to Calendly, false in a test run.
  • {{ data.<step>.eventUuid }} — string. Cancel a scheduled event only: the identifier extracted from the event URI.
  • {{ data.<step>.reason }} — string. Cancel a scheduled event only: the cancellation reason sent, empty when none was given.
  • {{ data.<step>.simulated }} — boolean. true when the action was described rather than performed. Only Cancel a scheduled event is ever simulated, in a test run; the reading actions always run for real.
  • {{ data.<step>.summary }} — string. A one-line summary in the member's language, for example '3 event types read.' (with summaryKey and summaryParams).

Operations ​

The node has one Action parameter (action). Each action calls the Calendly API with the connection's token.

  • List my event types (eventTypes, the default). Reads the account (GET /users/me), then its active event types (GET /event_types, sorted by name), up to Maximum count (limit, 1 to 100, default 20). With Event type (eventType) filled in, only that event type is kept: this is how you get the booking link of one specific type. Publishes eventTypes, count, schedulingUrl, truncated.
  • List scheduled events (events). Reads the account, then its scheduled events (GET /scheduled_events), earliest first, up to Maximum count. Filters: Status (status: active by default, canceled, or any), Event type, From (minStartTime) and To (maxStartTime), both ISO 8601 instants such as 2026-09-22T00:00:00Z; an empty bound means no bound. Publishes events, count, truncated.
  • Get one scheduled event (event). Reads the event designated by Scheduled event (eventUri), then, with Include invitees (withInvitees, on by default), its invitees in a second request. Publishes event, invitees, inviteeName, inviteeEmail.
  • Cancel a scheduled event (cancel). Cancels the event designated by Scheduled event, with the optional Cancellation reason (reason). Calendly notifies the invitee itself; this cannot be turned off. Publishes cancelled, eventUuid, reason.
  • Get my account (me). Reads the account of the connection. Publishes user.

Every action also publishes simulated and summary.

Scheduled event accepts the full URI (https://api.calendly.com/scheduled_events/…), as events returns it, or the bare identifier: the node keeps the last segment of the URI.

Example ​

A prospect asks for a meeting. The workflow lists the "Discovery call" event type and answers with its booking link. The node is named "Booking link", so its data lives under booking_link:

text
connection   Calendly — sales team
action       eventTypes
eventType    (list mode) Discovery call — 30 min
limit        20

The step data reads:

json
{
  "eventTypes": [
    {
      "uri": "https://api.calendly.com/event_types/AAAA1111",
      "name": "Discovery call — 30 min",
      "durationMinutes": 30,
      "schedulingUrl": "https://calendly.com/sales-team/discovery",
      "description": ""
    }
  ],
  "count": 1,
  "schedulingUrl": "https://calendly.com/sales-team/discovery",
  "truncated": false,
  "simulated": false
}

A Compose step then writes "You can book a slot here: {{ data.booking_link.schedulingUrl }}".

To cancel an appointment found by a list, chain a second Calendly node with action set to cancel and Scheduled event set to {{ data.appointments.events.0.uri }} (where appointments is the name of the list step).

Tips ​

  • Test runs. The four reading actions run for real in test runs: the preview shows your actual event types and appointments. Cancel a scheduled event is only described: nothing is sent to Calendly, cancelled is false and simulated is true.
  • Replays. Reading actions can be replayed safely. Cancel a scheduled event does not check the event's status first: if the engine replays the step after an incident, the cancellation request is sent again.
  • Two requests for a list. Calendly requires the account URI to list event types and scheduled events, so the node reads /users/me first. Each list therefore costs one more request.
  • Missing event. An empty Scheduled event fails the step with node_invalid_param. An unknown event fails with integration.not_found.
  • Errors. integration.unauthorized: the token was refused or revoked; create a new one and update the connection. integration.rate_limited and integration.unavailable are retried automatically: requests are paced to 60 per minute per connection, and a 409, 429 or 5xx answer gets up to three attempts (honouring Retry-After) before the engine retries the step later. See Error handling.