Calendly Scheduling ExecModule
Overview
CalendlySchedulingModule connects ValkyrAI workflows to Calendly API v2 and the Scheduling API. Version 2.0 replaces empty catalog I/O metadata and incorrect legacy routes with five explicit operations: authenticated-user lookup, bounded scheduled-event listing, available-time lookup, invitee creation, and scheduled-event cancellation.
The module requires a READY IntegrationAccount, keeps credentials in the authorization header, validates resource URIs and request bounds before transport, retries only safe reads, and never exposes provider bodies or credential material in failures. Booking and cancellation are external writes and are never retried automatically.
Usage
- Create a Calendly personal access token for an internal workflow or complete OAuth authorization for a customer-facing integration.
- Grant only the scopes needed by the selected operations.
- Store the token only in a ValkyrAI IntegrationAccount
apiKey, mark the accountREADY, and bind it throughExecModuleConfig.authConfig.integrationAccount. - Use
get_userto identify the authorized user, then choose a specific operation. - For booking, first call
list_available_times, present or approve one returned slot, then executeschedule_eventonce. - For cancellation, use the stable scheduled-event UUID and route the write through any required approval policy.
Inputs
| Name | Type | Required | Description | Constraints |
|---|---|---|---|---|
operation | string | Yes | Operation to run. | get_user, list_events, list_available_times, schedule_event, or cancel_event. Legacy action is accepted. |
event_type_uri | string | Availability, booking | Calendly event type resource URI. | Must be https://api.calendly.com/event_types/{id}. Legacy event_type is accepted. |
start_time | RFC3339 string | Availability, booking | Window or booking start. | Must contain an offset. Legacy startTime is accepted. |
end_time | RFC3339 string | Availability | Availability window end. | Must be after start_time and no more than seven days later. |
invitee | object | Booking | Invitee identity. | Requires bounded name, valid email, and IANA timezone. |
location | object | Event-type dependent | Scheduling API location selection. | If supplied, requires kind; additional provider fields are preserved. |
event_guests | array | No | Additional invitee email addresses. | At most 10 items; Calendly applies final validation. |
questions_and_answers | array | No | Event-type question responses. | At most 10 items; Calendly applies final schema validation. |
event_uuid | string | Cancellation | Scheduled event identifier. | 8–128 bounded identifier characters. Legacy event_id is accepted. |
reason | string | No | Cancellation reason. | At most 500 Unicode code points. |
scope_uri | string | Event list | Calendly user or organization resource URI. | Its resource family must match scope_type. |
scope_type | string | No | List scope. | user or organization; defaults to user. |
status | string | No | Scheduled-event status filter. | active or canceled; defaults to active. |
count | integer | No | Provider page size. | 1–100; defaults to 50. |
max_pages | integer | No | Maximum event-list pages. | 1–10; defaults to 3. |
safe_read_retries | integer | No | Transient GET retries. | 0–2; defaults to 1. Writes always use zero retries. |
Every serialized write request is capped at 100,000 UTF-8 bytes. Provider responses are capped at 2,000,000 UTF-8 bytes.
Outputs
| Name | Type | When present | Description |
|---|---|---|---|
calendly.operation | string | Success | Normalized operation name. |
calendly.data | JSON string | Success | Validated provider resource or bounded collection. |
calendly.item_count | integer string | Collection read | Number of events collected across bounded pages. |
calendly.next_page_token | string | More pages remain | Opaque continuation token when max_pages stops the read. |
calendly.event_uuid | string | Booking or cancellation | Scheduled event UUID returned by Calendly or supplied for cancellation. |
calendly.status | string | Always | SUCCESS after validated completion or ERROR on failure. |
The runtime ExecModule is marked GOOD or ERROR. EventLogs contain bounded operation progress and sanitized errors, never tokens, invitee payloads, or provider response bodies.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Calendly |
| Authentication | Personal access token or OAuth 2.1 access token |
| Status | READY |
accountName | Human-readable Calendly identity or tenant label |
apiKey | Encrypted PAT or OAuth access token |
password | Unused |
| Relationship | Bind through ExecModuleConfig.authConfig.integrationAccount |
Use the least required Calendly scopes:
users:readforget_user.scheduled_events:readforlist_events.event_types:readforlist_available_times.scheduled_events:writeforschedule_eventandcancel_event.
Some Scheduling API operations and rate limits depend on the Calendly subscription. OAuth applications should refresh rotating tokens before workflow execution. Never place a token in module inputs, URLs, examples, logs, or error messages.
Configuration
Illustrative booking configuration:
{
"version": "2.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:calendly-sales"
},
"payloadConfig": {
"parameters": "{\"operation\":\"schedule_event\",\"event_type_uri\":\"https://api.calendly.com/event_types/AAAAAAAAAAAAAAAA\",\"start_time\":\"2030-08-12T17:00:00Z\",\"invitee\":{\"name\":\"Jordan Lee\",\"email\":\"jordan@example.com\",\"timezone\":\"America/Los_Angeles\"}}"
}
}
The account value is a symbolic secure reference. Persisted workflows use the generated IntegrationAccount relationship, never a plaintext token. Default transport timeouts are 10 seconds to connect and 30 seconds to read.
Operations
| Operation | Provider request | Side effect and retry policy |
|---|---|---|
get_user | GET /users/me | Read-only; retries configured transient 408, 429, and 5xx failures. |
list_events | GET /scheduled_events with user/organization, status, count, and opaque page token | Read-only; follows at most max_pages; retries configured transient failures. |
list_available_times | GET /event_type_available_times with event type and bounded window | Read-only; retries configured transient failures. |
schedule_event | POST /invitees | Creates a booking; single attempt, no automatic retry. |
cancel_event | POST /scheduled_events/{uuid}/cancellation | Cancels an event; single attempt, no automatic retry. |
The module does not support arbitrary URLs, rescheduling, event-type mutation, webhook administration, routing forms, no-show mutation, contacts, or deletion of compliance data.
Errors and Failure Modes
| Failure | Cause | Retry guidance |
|---|---|---|
| Validation failure | Unsupported operation, malformed URI/time/email/timezone, excessive window/page/payload bound, or missing operation-specific field. | Correct the input; no Calendly request was sent. |
| IntegrationAccount failure | Missing account, non-READY status, or blank PAT/OAuth token. | Bind or reauthorize the account; no Calendly request was sent. |
| HTTP 401/403 | Expired token, missing scope, plan restriction, or insufficient object access. | Reauthorize with least required scope and verify Calendly account access. |
| HTTP 408/429/5xx on a read | Transient timeout, throttling, or provider failure. | The module retries only up to safe_read_retries; schedule a later read if exhausted. |
| HTTP/network failure on a write | Provider or transport failure with an ambiguous commit boundary. | Inspect Calendly for the booking/cancellation before a deliberate new execution. |
| Invalid success response | Missing collection/resource shape, non-JSON body, excessive response, or booking without an event/invitee resource. | Treat as failure and verify provider compatibility; success is not recorded. |
Provider response bodies can contain invitee data and support details. They are not copied into errors. HTTP failures expose only status and retry guidance, and errors do not retain the provider exception as a cause.
Example
After list_available_times returns and a workflow approves 2030-08-12T17:00:00Z, create one booking:
{
"operation": "schedule_event",
"event_type_uri": "https://api.calendly.com/event_types/AAAAAAAAAAAAAAAA",
"start_time": "2030-08-12T17:00:00Z",
"invitee": {
"name": "Jordan Lee",
"email": "jordan@example.com",
"timezone": "America/Los_Angeles"
},
"location": {
"kind": "zoom_conference"
}
}
Expected normalized result after Calendly returns a verified resource:
{
"calendly.operation": "schedule_event",
"calendly.event_uuid": "BBBBBBBBBBBBBBBB",
"calendly.status": "SUCCESS"
}
Notes
- Pagination:
list_eventsfollows only Calendly's opaquenext_page_token, never a provider-supplied absolute URL. It stops at provider exhaustion ormax_pagesand returns the token when more data remains. - Limits: availability windows are limited to seven days, event pages to 100 items and 10 pages, guest/question arrays to 10 entries, cancellation reasons to 500 code points, writes to 100 KB, and responses to 2 MB.
- Rate limits: transient safe reads retry at most twice beyond the initial request. Calendly enforces additional account, endpoint, and billing-tier limits.
- Idempotency: the module is not globally idempotent. Booking and cancellation are never automatically retried because a timeout can occur after Calendly commits the write. Reconcile provider state before repeating either operation.
- API constraints: booking uses the Scheduling API's
POST /invitees; the chosen event type, time, invitee, location, plan, and authorization must satisfy Calendly's current rules. - Rescheduling: Calendly does not expose direct rescheduling through this operation set. Use provider cancellation/reschedule links or an approved cancel-and-book workflow with explicit human intent.
- Destructive behavior: cancellation changes the external event and can notify participants. It requires an explicit operation and stable event UUID but has no automatic compensation.
- Privacy: returned event and invitee data is classified confidential. Keep downstream mappings, logs, and exports within authorized workflow boundaries.
- Unverified boundary: deterministic tests cover exact request routes and payloads, opaque pagination, bounds, safe-read retry, single-attempt writes, metadata serialization, IntegrationAccount binding, response validation, and secret redaction. Live Calendly execution requires separately authorized credentials and is not exercised in repository tests.
See Calendly's official Scheduling API guide, scope reference, and availability guide for current provider behavior.