Acuity Scheduling logo

Acuity Scheduling

CommunityPopular
LeoYeAI
acuity-scheduling

Acuity 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).

Overview

PublisherLeoYeAI
Repositoryopenclaw-master-skills
Skill nameacuity-scheduling
Stars
2.1K
Forks
325
Bundled files
1
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by LeoYeAI on GitHub. Read the source before you install it.

Installation

Install the Acuity Scheduling AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git /tmp/openclaw-master-skills
mkdir -p .claude/skills
cp -r /tmp/openclaw-master-skills/skills/acuity-scheduling .claude/skills/acuity-scheduling
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Acuity Scheduling in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Acuity Scheduling on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Acuity Scheduling is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Acuity Scheduling

Access the Acuity Scheduling API with managed OAuth authentication. Manage appointments, calendars, clients, availability, and more.

Quick Start

bash
# 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

Base URL

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.

Authentication

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:

bash
export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Acuity Scheduling OAuth connections at https://ctrl.maton.ai.

List Connections

bash
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

Create Connection

bash
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

Get Connection

bash
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:

json
{
  "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.

Delete Connection

bash
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

Specifying Connection

If you have multiple Acuity Scheduling connections, specify which one to use with the Maton-Connection header:

bash
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.

API Reference

Account Information

Get Account Info
bash
GET /acuity-scheduling/api/v1/me

Returns account information including timezone, scheduling page URL, and plan details.

Response:

json
{
  "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"
}

Appointments

List Appointments
bash
GET /acuity-scheduling/api/v1/appointments

Query Parameters:

ParameterTypeDescription
maxintegerMaximum results (default: 100)
minDatedateAppointments on or after this date
maxDatedateAppointments on or before this date
calendarIDintegerFilter by calendar
appointmentTypeIDintegerFilter by appointment type
canceledbooleanInclude canceled appointments (default: false)
firstNamestringFilter by client first name
lastNamestringFilter by client last name
emailstringFilter by client email
excludeFormsbooleanOmit intake forms for faster response
directionstringSort order: ASC or DESC (default: DESC)

Example:

bash
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:

json
[
  {
    "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 Appointment
bash
GET /acuity-scheduling/api/v1/appointments/{id}
Create Appointment
bash
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 ID
  • firstName - Client's first name
  • lastName - Client's last name
  • email - Client's email

Optional Fields:

  • phone - Client phone number
  • calendarID - Specific calendar (auto-selected if omitted)
  • timezone - Client's timezone
  • certificate - Package or coupon code
  • notes - Admin notes
  • addonIDs - Array of addon IDs
  • fields - Array of form field values

Example:

bash
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
Update Appointment
bash
PUT /acuity-scheduling/api/v1/appointments/{id}
Content-Type: application/json

{
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com"
}
Cancel Appointment
bash
PUT /acuity-scheduling/api/v1/appointments/{id}/cancel

Returns the canceled appointment with canceled: true.

Reschedule Appointment
bash
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.

Calendars

List Calendars
bash
GET /acuity-scheduling/api/v1/calendars

Response:

json
[
  {
    "id": 13499175,
    "name": "Chris",
    "email": "",
    "replyTo": "chris@example.com",
    "description": "",
    "location": "",
    "timezone": "America/Los_Angeles"
  }
]

Appointment Types

List Appointment Types
bash
GET /acuity-scheduling/api/v1/appointment-types

Query Parameters:

  • includeDeleted (boolean) - Include deleted types

Response:

json
[
  {
    "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?..."
  }
]

Availability

Get Available Dates
bash
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 ID

Optional Parameters:

  • calendarID - Specific calendar
  • timezone - Timezone for results (e.g., "America/New_York")

Response:

json
[
  {"date": "2026-02-09"},
  {"date": "2026-02-10"},
  {"date": "2026-02-11"}
]
Get Available Times
bash
GET /acuity-scheduling/api/v1/availability/times?date=2026-02-10&appointmentTypeID=123

Required Parameters:

  • date - Date to check
  • appointmentTypeID - Appointment type ID

Optional Parameters:

  • calendarID - Specific calendar
  • timezone - Timezone for results

Response:

json
[
  {"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}
]

Clients

List Clients
bash
GET /acuity-scheduling/api/v1/clients

Query Parameters:

  • search - Filter by first name, last name, or phone

Example:

bash
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:

json
[
  {
    "firstName": "Jane",
    "lastName": "McTest",
    "email": "jane.mctest@example.com",
    "phone": "(123) 555-0101",
    "notes": ""
  }
]
Create Client
bash
POST /acuity-scheduling/api/v1/clients
Content-Type: application/json

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "phone": "555-123-4567"
}
Update Client
bash
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 Client
bash
DELETE /acuity-scheduling/api/v1/clients
Content-Type: application/json

{
  "firstName": "John",
  "lastName": "Doe"
}

Blocks

List Blocks
bash
GET /acuity-scheduling/api/v1/blocks

Query Parameters:

  • max - Maximum results (default: 100)
  • minDate - Blocks on or after this date
  • maxDate - Blocks on or before this date
  • calendarID - Filter by calendar
Get Block
bash
GET /acuity-scheduling/api/v1/blocks/{id}
Create Block
bash
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:

json
{
  "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 Block
bash
DELETE /acuity-scheduling/api/v1/blocks/{id}

Returns 204 No Content on success.

Forms

List Forms
bash
GET /acuity-scheduling/api/v1/forms

Response:

json
[
  {
    "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
      }
    ]
  }
]

Labels

List Labels
bash
GET /acuity-scheduling/api/v1/labels

Response:

json
[
  {"id": 23116714, "name": "Checked In", "color": "green"},
  {"id": 23116715, "name": "Completed", "color": "pink"},
  {"id": 23116713, "name": "Confirmed", "color": "yellow"}
]

Pagination

Acuity Scheduling uses the max parameter to limit results. Use minDate and maxDate to paginate through date ranges:

bash
# 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

Code Examples

JavaScript

javascript
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();

Python

python
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()

Notes

  • Datetime values must be parseable by PHP's strtotime() function
  • Timezones use IANA format (e.g., "America/New_York", "America/Los_Angeles")
  • Client update/delete requires clients to have existing appointments
  • Rescheduling requires the new datetime to be an available time slot
  • Use excludeForms=true for faster appointment list responses
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • IMPORTANT: When piping curl output to jq 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.

Error Handling

StatusMeaning
400Invalid request (e.g., time not available, client not found)
401Invalid or missing Maton API key
404Resource not found
429Rate limited
4xx/5xxPassthrough error from Acuity API

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
bash
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
bash
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

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with acuity-scheduling. For example:
  • Correct: https://gateway.maton.ai/acuity-scheduling/api/v1/appointments
  • Incorrect: https://gateway.maton.ai/api/v1/appointments

Resources

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Acuity Scheduling AI skill do?

Acuity 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).

Why use Acuity Scheduling on TypingMind?

Because you install it once and use it with any model. Acuity Scheduling is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Acuity Scheduling in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/acuity-scheduling. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Acuity Scheduling?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Acuity Scheduling?

As many as you like. As long as a model supports skills, you can use Acuity Scheduling with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Acuity Scheduling AI skill free?

Yes. It is published on GitHub by LeoYeAI under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇