acuity-schedulingAcuity Scheduling API integration with managed OAuth. Manage appointments, calendars, clients, and availability. Use this skill when users want to schedule, reschedule, or cancel appointments, check availability, or manage clients and calendars. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Install via ClawdBot CLI:
clawdbot install byungkyu/acuity-schedulingAccess the Acuity Scheduling API with managed OAuth authentication. Manage appointments, calendars, clients, availability, and more.
# List appointments
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/acuity-scheduling/api/v1/appointments?max=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://gateway.maton.ai/acuity-scheduling/{native-api-path}
Replace {native-api-path} with the actual Acuity API endpoint path. The gateway proxies requests to acuityscheduling.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 Acuity Scheduling OAuth connections at https://ctrl.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=acuity-scheduling&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': 'acuity-scheduling'}).encode()
req = urllib.request.Request('https://ctrl.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://ctrl.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": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"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": "acuity-scheduling",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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 Acuity Scheduling connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/acuity-scheduling/api/v1/appointments')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
GET /acuity-scheduling/api/v1/me
Returns account information including timezone, scheduling page URL, and plan details.
Response:
{
"id": 12345,
"email": "user@example.com",
"timezone": "America/Los_Angeles",
"name": "My Business",
"schedulingPage": "https://app.acuityscheduling.com/schedule.php?owner=12345",
"plan": "Professional",
"currency": "USD"
}
GET /acuity-scheduling/api/v1/appointments
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| max | integer | Maximum results (default: 100) |
| minDate | date | Appointments on or after this date |
| maxDate | date | Appointments on or before this date |
| calendarID | integer | Filter by calendar |
| appointmentTypeID | integer | Filter by appointment type |
| canceled | boolean | Include canceled appointments (default: false) |
| firstName | string | Filter by client first name |
| lastName | string | Filter by client last name |
| email | string | Filter by client email |
| excludeForms | boolean | Omit intake forms for faster response |
| direction | string | Sort order: ASC or DESC (default: DESC) |
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/acuity-scheduling/api/v1/appointments?max=10&minDate=2026-02-01')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
[
{
"id": 1630290133,
"firstName": "Jane",
"lastName": "McTest",
"phone": "1235550101",
"email": "jane.mctest@example.com",
"date": "February 4, 2026",
"time": "9:30am",
"endTime": "10:20am",
"datetime": "2026-02-04T09:30:00-0800",
"type": "Consultation",
"appointmentTypeID": 88791369,
"duration": "50",
"calendar": "Chris",
"calendarID": 13499175,
"canceled": false,
"confirmationPage": "https://app.acuityscheduling.com/schedule.php?..."
}
]
GET /acuity-scheduling/api/v1/appointments/{id}
POST /acuity-scheduling/api/v1/appointments
Content-Type: application/json
{
"datetime": "2026-02-15T09:00",
"appointmentTypeID": 123,
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "555-123-4567",
"timezone": "America/New_York"
}
Required Fields:
datetime - Date and time (parseable by PHP's strtotime)appointmentTypeID - Appointment type IDfirstName - Client's first namelastName - Client's last nameemail - Client's emailOptional Fields:
phone - Client phone numbercalendarID - Specific calendar (auto-selected if omitted)timezone - Client's timezonecertificate - Package or coupon codenotes - Admin notesaddonIDs - Array of addon IDsfields - Array of form field valuesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({
'datetime': '2026-02-15T09:00',
'appointmentTypeID': 123,
'firstName': 'John',
'lastName': 'Doe',
'email': 'john.doe@example.com'
}).encode()
req = urllib.request.Request('https://gateway.maton.ai/acuity-scheduling/api/v1/appointments', 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
PUT /acuity-scheduling/api/v1/appointments/{id}
Content-Type: application/json
{
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com"
}
PUT /acuity-scheduling/api/v1/appointments/{id}/cancel
Returns the canceled appointment with canceled: true.
PUT /acuity-scheduling/api/v1/appointments/{id}/reschedule
Content-Type: application/json
{
"datetime": "2026-02-20T10:00"
}
Note: The new datetime must be an available time slot.
GET /acuity-scheduling/api/v1/calendars
Response:
[
{
"id": 13499175,
"name": "Chris",
"email": "",
"replyTo": "chris@example.com",
"description": "",
"location": "",
"timezone": "America/Los_Angeles"
}
]
GET /acuity-scheduling/api/v1/appointment-types
Query Parameters:
includeDeleted (boolean) - Include deleted typesResponse:
[
{
"id": 88791369,
"name": "Consultation",
"active": true,
"description": "",
"duration": 50,
"price": "45.00",
"category": "",
"color": "#ED7087",
"private": false,
"type": "service",
"calendarIDs": [13499175],
"schedulingUrl": "https://app.acuityscheduling.com/schedule.php?..."
}
]
GET /acuity-scheduling/api/v1/availability/dates?month=2026-02&appointmentTypeID=123
Required Parameters:
month - Month to check (e.g., "2026-02")appointmentTypeID - Appointment type IDOptional Parameters:
calendarID - Specific calendartimezone - Timezone for results (e.g., "America/New_York")Response:
[
{"date": "2026-02-09"},
{"date": "2026-02-10"},
{"date": "2026-02-11"}
]
GET /acuity-scheduling/api/v1/availability/times?date=2026-02-10&appointmentTypeID=123
Required Parameters:
date - Date to checkappointmentTypeID - Appointment type IDOptional Parameters:
calendarID - Specific calendartimezone - Timezone for resultsResponse:
[
{"time": "2026-02-10T09:00:00-0800", "slotsAvailable": 1},
{"time": "2026-02-10T09:50:00-0800", "slotsAvailable": 1},
{"time": "2026-02-10T10:40:00-0800", "slotsAvailable": 1}
]
GET /acuity-scheduling/api/v1/clients
Query Parameters:
search - Filter by first name, last name, or phoneExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/acuity-scheduling/api/v1/clients?search=John')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
[
{
"firstName": "Jane",
"lastName": "McTest",
"email": "jane.mctest@example.com",
"phone": "(123) 555-0101",
"notes": ""
}
]
POST /acuity-scheduling/api/v1/clients
Content-Type: application/json
{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"phone": "555-123-4567"
}
PUT /acuity-scheduling/api/v1/clients
Content-Type: application/json
{
"firstName": "John",
"lastName": "Doe",
"email": "john.updated@example.com"
}
Note: Client update/delete only works for clients with existing appointments.
DELETE /acuity-scheduling/api/v1/clients
Content-Type: application/json
{
"firstName": "John",
"lastName": "Doe"
}
GET /acuity-scheduling/api/v1/blocks
Query Parameters:
max - Maximum results (default: 100)minDate - Blocks on or after this datemaxDate - Blocks on or before this datecalendarID - Filter by calendarGET /acuity-scheduling/api/v1/blocks/{id}
POST /acuity-scheduling/api/v1/blocks
Content-Type: application/json
{
"start": "2026-02-15T12:00",
"end": "2026-02-15T13:00",
"calendarID": 1234,
"notes": "Lunch break"
}
Response:
{
"id": 9589304654,
"calendarID": 13499175,
"start": "2026-02-15T12:00:00-0800",
"end": "2026-02-15T13:00:00-0800",
"notes": "Lunch break",
"description": "Sunday, February 15, 2026 12:00pm - 1:00pm"
}
DELETE /acuity-scheduling/api/v1/blocks/{id}
Returns 204 No Content on success.
GET /acuity-scheduling/api/v1/forms
Response:
[
{
"id": 123,
"name": "Client Intake Form",
"appointmentTypeIDs": [456, 789],
"fields": [
{
"id": 1,
"name": "How did you hear about us?",
"type": "dropdown",
"options": ["Google", "Friend", "Social Media"],
"required": true
}
]
}
]
GET /acuity-scheduling/api/v1/labels
Response:
[
{"id": 23116714, "name": "Checked In", "color": "green"},
{"id": 23116715, "name": "Completed", "color": "pink"},
{"id": 23116713, "name": "Confirmed", "color": "yellow"}
]
Acuity Scheduling uses the max parameter to limit results. Use minDate and maxDate to paginate through date ranges:
# First page
GET /acuity-scheduling/api/v1/appointments?max=100&minDate=2026-01-01&maxDate=2026-01-31
# Next page
GET /acuity-scheduling/api/v1/appointments?max=100&minDate=2026-02-01&maxDate=2026-02-28
const response = await fetch(
'https://gateway.maton.ai/acuity-scheduling/api/v1/appointments?max=10',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const appointments = await response.json();
import os
import requests
response = requests.get(
'https://gateway.maton.ai/acuity-scheduling/api/v1/appointments',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'max': 10}
)
appointments = response.json()
strtotime() functionexcludeForms=true for faster appointment list responsescurl -g when URLs contain brackets to disable glob parsingjq 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 | Invalid request (e.g., time not available, client not found) |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Acuity API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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
acuity-scheduling. For example:https://gateway.maton.ai/acuity-scheduling/api/v1/appointmentshttps://gateway.maton.ai/api/v1/appointmentsGenerated Mar 1, 2026
A medical clinic uses the skill to automate appointment scheduling, rescheduling, and cancellations for patients. It integrates with their existing calendar system to check doctor availability and send reminders, reducing no-shows and administrative workload.
A fitness studio leverages the skill to allow clients to book, modify, or cancel fitness classes online. It syncs with instructor calendars to manage availability and class capacities, streamlining operations and improving customer experience.
A consulting firm uses the skill to schedule client meetings and consultations across multiple time zones. It manages client details and appointment types, ensuring efficient time management and professional service delivery.
A salon employs the skill to handle appointments for various services like haircuts, massages, and treatments. It tracks client preferences and staff availability, optimizing scheduling and reducing overbooking issues.
An online tutoring platform integrates the skill to schedule and manage tutoring sessions between students and tutors. It checks tutor availability and handles rescheduling requests, enhancing learning continuity and resource allocation.
Offer the skill as part of a subscription service where businesses pay a monthly fee for access to scheduling features. This model provides recurring revenue and can include tiered plans based on usage or advanced functionalities.
Provide basic scheduling capabilities for free to attract users, then charge for premium features like advanced analytics, custom integrations, or priority support. This model drives user adoption and upsell opportunities.
License the skill to other companies or developers who rebrand it as their own scheduling solution. This model generates revenue through licensing fees or revenue-sharing agreements, expanding market reach without direct sales efforts.
💬 Integration Tip
Ensure the MATON_API_KEY is securely stored as an environment variable and test connection management via the control panel before deploying to production.
Interact with Google Calendar via the Google Calendar API – list upcoming events, create new events, update or delete them. Use this skill when you need programmatic access to your calendar from OpenClaw.
Read, search, and manage Outlook emails and calendar via Microsoft Graph API. Use when the user asks about emails, inbox, Outlook, Microsoft mail, calendar events, or scheduling.
Google Calendar via gcalcli: today-only agenda by default, bounded meaning-first lookup via agenda scans, and fast create/delete with verification--optimized for low tool calls and minimal output.
This skill should be used when interacting with Apple Calendar on macOS. Use it for listing calendars, viewing events, creating/updating/deleting calendar events, and checking availability/free-busy times. Triggers on requests like "check my calendar", "schedule a meeting", "what's on my schedule", "am I free tomorrow", or any calendar-related operations.
Access and manage Google Calendar events with gogcli for cross-calendar agendas, keyword search, and filtered outputs avoiding unwanted calendars like holidays.
Daily morning rollup of important emails and calendar events at 8am with AI-generated summaries