Access the Calendly API with managed OAuth authentication. Retrieve event types, scheduled events, invitees, availability data, and manage webhook subscriptions for scheduling automation.
# Get current user
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/users/me')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/calendly/{native-api-path}
Maton proxies requests to api.calendly.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Calendly OAuth connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=calendly&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'calendly'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "calendly",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Calendly connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/users/me')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
GET /calendly/users/me
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/users/me')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"resource": {
"uri": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA",
"name": "Alice Johnson",
"slug": "alice-johnson",
"email": "alice.johnson@acme.com",
"scheduling_url": "https://calendly.com/alice-johnson",
"timezone": "America/New_York",
"avatar_url": "https://example.com/avatar.png",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2025-06-20T14:45:00.000000Z",
"current_organization": "https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB"
}
}
GET /calendly/users/{uuid}
GET /calendly/event_types
Query parameters:
user - User URI to filter event typesorganization - Organization URI to filter event typesactive - Filter by active status (true/false)count - Number of results to return (default 20, max 100)page_token - Token for paginationsort - Sort order (e.g., name:asc, created_at:desc)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/event_types?user=https://api.calendly.com/users/AAAAAAAAAAAAAAAA&active=true')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"uri": "https://api.calendly.com/event_types/CCCCCCCCCCCCCCCC",
"name": "30 Minute Meeting",
"active": true,
"slug": "30min",
"scheduling_url": "https://calendly.com/alice-johnson/30min",
"duration": 30,
"kind": "solo",
"type": "StandardEventType",
"color": "#0066FF",
"created_at": "2024-02-01T09:00:00.000000Z",
"updated_at": "2025-05-15T11:30:00.000000Z",
"description_plain": "A quick 30-minute catch-up call",
"description_html": "<p>A quick 30-minute catch-up call</p>",
"profile": {
"type": "User",
"name": "Alice Johnson",
"owner": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA"
}
}
],
"pagination": {
"count": 1,
"next_page_token": null
}
}
GET /calendly/event_types/{uuid}
GET /calendly/scheduled_events
Query parameters:
user - User URI to filter eventsorganization - Organization URI to filter eventsinvitee_email - Filter by invitee emailstatus - Filter by status (active, canceled)min_start_time - Filter events starting after this time (ISO 8601)max_start_time - Filter events starting before this time (ISO 8601)count - Number of results (default 20, max 100)page_token - Token for paginationsort - Sort order (e.g., start_time:asc)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/scheduled_events?user=https://api.calendly.com/users/AAAAAAAAAAAAAAAA&status=active&min_start_time=2025-03-01T00:00:00Z')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"uri": "https://api.calendly.com/scheduled_events/DDDDDDDDDDDDDDDD",
"name": "30 Minute Meeting",
"status": "active",
"start_time": "2025-03-15T14:00:00.000000Z",
"end_time": "2025-03-15T14:30:00.000000Z",
"event_type": "https://api.calendly.com/event_types/CCCCCCCCCCCCCCCC",
"location": {
"type": "zoom",
"join_url": "https://zoom.us/j/123456789"
},
"invitees_counter": {
"total": 1,
"active": 1,
"limit": 1
},
"created_at": "2025-03-10T09:15:00.000000Z",
"updated_at": "2025-03-10T09:15:00.000000Z",
"event_memberships": [
{
"user": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA"
}
]
}
],
"pagination": {
"count": 1,
"next_page_token": null
}
}
GET /calendly/scheduled_events/{uuid}
POST /calendly/scheduled_events/{uuid}/cancellation
Content-Type: application/json
{
"reason": "Meeting rescheduled"
}
Example:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'reason': 'Meeting rescheduled'}).encode()
req = urllib.request.Request('https://api.maton.ai/calendly/scheduled_events/DDDDDDDDDDDDDDDD/cancellation', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /calendly/scheduled_events/{event_uuid}/invitees
Query parameters:
status - Filter by status (active, canceled)email - Filter by invitee emailcount - Number of results (default 20, max 100)page_token - Token for paginationsort - Sort order (e.g., created_at:asc)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/scheduled_events/DDDDDDDDDDDDDDDD/invitees')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"uri": "https://api.calendly.com/scheduled_events/DDDDDDDDDDDDDDDD/invitees/EEEEEEEEEEEEEEEE",
"email": "bob.smith@example.com",
"name": "Bob Smith",
"status": "active",
"timezone": "America/Los_Angeles",
"event": "https://api.calendly.com/scheduled_events/DDDDDDDDDDDDDDDD",
"created_at": "2025-03-10T09:15:00.000000Z",
"updated_at": "2025-03-10T09:15:00.000000Z",
"questions_and_answers": [
{
"question": "What would you like to discuss?",
"answer": "Project timeline review",
"position": 0
}
],
"tracking": {
"utm_source": null,
"utm_medium": null,
"utm_campaign": null
},
"cancel_url": "https://calendly.com/cancellations/EEEEEEEEEEEEEEEE",
"reschedule_url": "https://calendly.com/reschedulings/EEEEEEEEEEEEEEEE"
}
],
"pagination": {
"count": 1,
"next_page_token": null
}
}
GET /calendly/scheduled_events/{event_uuid}/invitees/{invitee_uuid}
Schedule a meeting programmatically by creating an invitee. Requires a paid Calendly plan.
POST /calendly/event_types/{event_type_uuid}/invitees
Content-Type: application/json
{
"start_time": "2025-03-20T15:00:00Z",
"email": "bob.smith@example.com",
"name": "Bob Smith",
"timezone": "America/Los_Angeles",
"location": {
"kind": "zoom"
},
"questions_and_answers": [
{
"question_uuid": "QQQQQQQQQQQQQQQ",
"answer": "Project timeline review"
}
]
}
Example:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'start_time': '2025-03-20T15:00:00Z', 'email': 'bob.smith@example.com', 'name': 'Bob Smith'}).encode()
req = urllib.request.Request('https://api.maton.ai/calendly/event_types/CCCCCCCCCCCCCCCC/invitees', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Note: The start_time must correspond to a valid available slot. Use the /event_type_available_times endpoint to find available times.
GET /calendly/event_type_available_times
Query parameters:
event_type - Event type URI (required)start_time - Start of time range (ISO 8601, required)end_time - End of time range (ISO 8601, required, max 7 days from start)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/event_type_available_times?event_type=https://api.calendly.com/event_types/CCCCCCCCCCCCCCCC&start_time=2025-03-15T00:00:00Z&end_time=2025-03-22T00:00:00Z')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"status": "available",
"invitees_remaining": 1,
"start_time": "2025-03-17T14:00:00.000000Z",
"scheduling_url": "https://calendly.com/alice-johnson/30min/2025-03-17T14:00:00Z"
},
{
"status": "available",
"invitees_remaining": 1,
"start_time": "2025-03-17T14:30:00.000000Z",
"scheduling_url": "https://calendly.com/alice-johnson/30min/2025-03-17T14:30:00Z"
}
]
}
GET /calendly/user_busy_times
Query parameters:
user - User URI (required)start_time - Start of time range (ISO 8601, required)end_time - End of time range (ISO 8601, required, max 7 days from start)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/user_busy_times?user=https://api.calendly.com/users/AAAAAAAAAAAAAAAA&start_time=2025-03-15T00:00:00Z&end_time=2025-03-22T00:00:00Z')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"type": "calendly",
"start_time": "2025-03-17T10:00:00.000000Z",
"end_time": "2025-03-17T11:00:00.000000Z"
},
{
"type": "external",
"start_time": "2025-03-18T14:00:00.000000Z",
"end_time": "2025-03-18T15:00:00.000000Z"
}
]
}
GET /calendly/user_availability_schedules
Query parameters:
user - User URI (required)Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/user_availability_schedules?user=https://api.calendly.com/users/AAAAAAAAAAAAAAAA')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
GET /calendly/organization_memberships
Query parameters:
organization - Organization URI (required)user - User URI to filteremail - Email to filtercount - Number of results (default 20, max 100)page_token - Token for paginationExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/organization_memberships?organization=https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"collection": [
{
"uri": "https://api.calendly.com/organization_memberships/FFFFFFFFFFFFFFFF",
"role": "admin",
"user": {
"uri": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA",
"name": "Alice Johnson",
"email": "alice.johnson@acme.com"
},
"organization": "https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2025-06-20T14:45:00.000000Z"
}
],
"pagination": {
"count": 1,
"next_page_token": null
}
}
Webhooks require a paid Calendly plan (Standard, Teams, or Enterprise).
GET /calendly/webhook_subscriptions
Query parameters:
organization - Organization URI (required)scope - Filter by scope (user, organization)user - User URI to filter (when scope is user)count - Number of results (default 20, max 100)page_token - Token for paginationExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/webhook_subscriptions?organization=https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB&scope=organization')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
POST /calendly/webhook_subscriptions
Content-Type: application/json
{
"url": "https://example.com/webhook",
"events": ["invitee.created", "invitee.canceled"],
"organization": "https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB",
"scope": "organization",
"signing_key": "your-secret-key"
}
Available events:
invitee.created - Triggered when an invitee schedules an eventinvitee.canceled - Triggered when an invitee cancels an eventrouting_form_submission.created - Triggered when a routing form is submittedExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'url': 'https://example.com/webhook', 'events': ['invitee.created', 'invitee.canceled'], 'organization': 'https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB', 'scope': 'organization'}).encode()
req = urllib.request.Request('https://api.maton.ai/calendly/webhook_subscriptions', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"resource": {
"uri": "https://api.calendly.com/webhook_subscriptions/GGGGGGGGGGGGGGGG",
"callback_url": "https://example.com/webhook",
"created_at": "2025-03-01T12:00:00.000000Z",
"updated_at": "2025-03-01T12:00:00.000000Z",
"retry_started_at": null,
"state": "active",
"events": ["invitee.created", "invitee.canceled"],
"scope": "organization",
"organization": "https://api.calendly.com/organizations/BBBBBBBBBBBBBBBB",
"user": null,
"creator": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA"
}
}
GET /calendly/webhook_subscriptions/{uuid}
DELETE /calendly/webhook_subscriptions/{uuid}
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/webhook_subscriptions/GGGGGGGGGGGGGGGG', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Returns 204 No Content on success.
Use page_token for pagination. Response includes pagination.next_page_token when more results exist:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/calendly/scheduled_events?user=USER_URI&page_token=NEXT_PAGE_TOKEN')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
const response = await fetch(
'https://api.maton.ai/calendly/scheduled_events?user=https://api.calendly.com/users/AAAAAAAAAAAAAAAA&status=active',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
import os
import requests
response = requests.get(
'https://api.maton.ai/calendly/scheduled_events',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={
'user': 'https://api.calendly.com/users/AAAAAAAAAAAAAAAA',
'status': 'active'
}
)
data = response.json()
https://api.calendly.com/users/AAAAAAAAAAAAAAAA)start_time must be in the futurejq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.| Status | Meaning |
|---|---|
| -------- | --------- |
| 400 | Bad request or missing Calendly connection |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - insufficient permissions or plan restrictions |
| 404 | Resource not found |
| 424 | External calendar error (calendar integration issue on Calendly side) |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Calendly API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
calendly. For example:https://api.maton.ai/calendly/users/mehttps://api.maton.ai/users/me共 2 个版本