Appointment Slots
Manage calendar windows — the recurring availability rules that define when and how many appointments can be booked. Each window belongs to a branch and repeats weekly on a fixed day and session.
Use GET /v1/appointment-slots/availability and GET /v1/appointment-slots/schedule-tracking to query what is open and how full slots are on specific dates. See Availability & Schedule Tracking.
Before You Begin
Your API key requires the slots:write scope for create, update, and disable operations.
slot_id Format
The slot_id field takes different forms depending on which endpoint you are calling:
| Context | Format | Example |
|---|---|---|
| Create / Update / Disable | Plain calendar_id UUID | "a1b2c3d4-..." |
| Availability response | calendar_id||YYYY-MM-DD | "a1b2c3d4-...||2026-06-15" |
| Schedule tracking response | calendar_id||YYYY-MM-DD||appointment_type_id | "a1b2c3d4-...||2026-06-15||f47ac10b-..." |
When passing a slot_id to PATCH or disable endpoints, the server extracts the first segment — so you can safely pass either the plain UUID or a compound value from an availability response.
Create a Calendar Window
- Endpoint:
POST https://api.huskyvoice.ai/v1/appointment-slots - Required scope:
slots:write
- cURL
- Python
- JavaScript
- n8n
curl -s -X POST https://api.huskyvoice.ai/v1/appointment-slots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"branch_id": "branch_uuid_here",
"day": "monday",
"session": "Morning",
"start_time": "09:00",
"end_time": "11:00",
"max_slots": 20,
"ai_slots": 10,
"batch_name": "MA",
"appointment_type_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}'
import requests
url = "https://api.huskyvoice.ai/v1/appointment-slots"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"branch_id": "branch_uuid_here",
"day": "monday",
"session": "Morning",
"start_time": "09:00",
"end_time": "11:00",
"max_slots": 20,
"ai_slots": 10,
"batch_name": "MA",
"appointment_type_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const response = await fetch("https://api.huskyvoice.ai/v1/appointment-slots", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
branch_id: "branch_uuid_here",
day: "monday",
session: "Morning",
start_time: "09:00",
end_time: "11:00",
max_slots: 20,
ai_slots: 10,
batch_name: "MA",
appointment_type_id: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
})
});
const data = await response.json();
console.log(data);
Create an HTTP Header Auth credential in n8n: set Name to Authorization and Value to Bearer YOUR_API_KEY. Select it in the HTTP Request node's Authentication field.
{
"name": "HuskyVoice – Create Calendar Window",
"nodes": [
{
"parameters": {
"method": "POST",
"url": "https://api.huskyvoice.ai/v1/appointment-slots",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\n \"branch_id\": \"branch_uuid_here\",\n \"day\": \"monday\",\n \"session\": \"Morning\",\n \"start_time\": \"09:00\",\n \"end_time\": \"11:00\",\n \"max_slots\": 20,\n \"ai_slots\": 10,\n \"batch_name\": \"MA\",\n \"appointment_type_id\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\"\n}"
},
"id": "1",
"name": "Create Calendar Window",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [250, 300]
}
],
"connections": {},
"settings": {},
"meta": { "instanceId": "huskyvoice-docs" }
}
Response — 201 Created
{
"success": true,
"data": {
"slot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"calendar_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"branch_id": "branch_uuid_here",
"day": "monday",
"session": "Morning",
"batch": "MA",
"start_time": "09:00",
"end_time": "11:00",
"appointment_type": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"max_slots": 20,
"ai_slots": 10,
"filled_slots": null,
"available_slots": null,
"status": "OPEN",
"created_at": "2026-05-26T10:00:00.000Z",
"updated_at": "2026-05-26T10:00:00.000Z"
}
}
Request Fields
| Field | Required | Description |
|---|---|---|
branch_id | Yes | Branch UUID this window belongs to |
day | Yes | Day of the week, lowercase (e.g. "monday", "tuesday") |
session | Yes | "Morning", "Afternoon", or "Evening" |
ai_slots | Yes | Maximum appointments the AI voice agent can book in this window |
max_slots | No | Total slot capacity for this window — defaults to ai_slots if omitted; must be ≥ ai_slots |
start_time | No | Window start time string (e.g. "09:00") |
end_time | No | Window end time string (e.g. "11:00") |
batch_name | No | Batch label (e.g. "MA") — auto-populated on appointments created within this window |
appointment_type_id | No | Restrict this window to a specific service UUID |
status | No | Initial status — "OPEN" (default) or "CLOSED" |
ai_slots controls how many slots the AI voice agent can fill. max_slots is the total capacity for the window. If your staff can handle 20 appointments but you only want the AI to book 10, set max_slots: 20 and ai_slots: 10.
Update a Calendar Window
- Endpoint:
PATCH https://api.huskyvoice.ai/v1/appointment-slots/{slot_id} - Required scope:
slots:write
Send only the fields you want to change. At least one field is required.
- cURL
- Python
- JavaScript
- n8n
curl -s -X PATCH https://api.huskyvoice.ai/v1/appointment-slots/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"max_slots": 25, "ai_slots": 15}'
import requests
slot_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
url = f"https://api.huskyvoice.ai/v1/appointment-slots/{slot_id}"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"max_slots": 25,
"ai_slots": 15
}
response = requests.patch(url, json=payload, headers=headers)
print(response.json())
const slotId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const response = await fetch(
`https://api.huskyvoice.ai/v1/appointment-slots/${slotId}`,
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ max_slots: 25, ai_slots: 15 })
}
);
const data = await response.json();
console.log(data);
Create an HTTP Header Auth credential in n8n: set Name to Authorization and Value to Bearer YOUR_API_KEY. Select it in the HTTP Request node's Authentication field.
{
"name": "HuskyVoice – Update Calendar Window",
"nodes": [
{
"parameters": {
"method": "PATCH",
"url": "https://api.huskyvoice.ai/v1/appointment-slots/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\n \"max_slots\": 25,\n \"ai_slots\": 15\n}"
},
"id": "1",
"name": "Update Calendar Window",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [250, 300]
}
],
"connections": {},
"settings": {},
"meta": { "instanceId": "huskyvoice-docs" }
}
Response — 200 OK
{
"success": true,
"data": {
"slot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"calendar_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"branch_id": "branch_uuid_here",
"day": "monday",
"session": "Morning",
"batch": "MA",
"start_time": "09:00",
"end_time": "11:00",
"appointment_type": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"max_slots": 25,
"ai_slots": 15,
"filled_slots": null,
"available_slots": null,
"status": "OPEN",
"created_at": "2026-05-26T10:00:00.000Z",
"updated_at": "2026-05-26T11:00:00.000Z"
}
}
Updatable Fields
| Field | Description |
|---|---|
day | Day of the week, lowercase |
session | "Morning", "Afternoon", or "Evening" |
start_time | Window start time string |
end_time | Window end time string |
max_slots | Total slot capacity — must be ≥ ai_slots |
ai_slots | AI agent slot limit — must be ≤ max_slots |
batch_name | Batch label |
status | "OPEN" or "CLOSED" |
Disable a Calendar Window
Sets a window's status to CLOSED, preventing new appointments from being booked into it. There is no delete operation — use disable to take a window offline.
- Endpoint:
POST https://api.huskyvoice.ai/v1/appointment-slots/{slot_id}/disable - Required scope:
slots:write
- cURL
- Python
- JavaScript
- n8n
curl -s -X POST https://api.huskyvoice.ai/v1/appointment-slots/a1b2c3d4-e5f6-7890-abcd-ef1234567890/disable \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
slot_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
url = f"https://api.huskyvoice.ai/v1/appointment-slots/{slot_id}/disable"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
response = requests.post(url, headers=headers)
print(response.json())
const slotId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const response = await fetch(
`https://api.huskyvoice.ai/v1/appointment-slots/${slotId}/disable`,
{
method: "POST",
headers: { "Authorization": "Bearer YOUR_API_KEY" }
}
);
const data = await response.json();
console.log(data);
Create an HTTP Header Auth credential in n8n: set Name to Authorization and Value to Bearer YOUR_API_KEY. Select it in the HTTP Request node's Authentication field.
{
"name": "HuskyVoice – Disable Calendar Window",
"nodes": [
{
"parameters": {
"method": "POST",
"url": "https://api.huskyvoice.ai/v1/appointment-slots/a1b2c3d4-e5f6-7890-abcd-ef1234567890/disable",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"id": "1",
"name": "Disable Calendar Window",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [250, 300]
}
],
"connections": {},
"settings": {},
"meta": { "instanceId": "huskyvoice-docs" }
}
Response — 200 OK
{
"success": true,
"data": {
"slot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"calendar_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"branch_id": "branch_uuid_here",
"day": "monday",
"session": "Morning",
"batch": "MA",
"start_time": "09:00",
"end_time": "11:00",
"appointment_type": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"max_slots": 20,
"ai_slots": 10,
"filled_slots": null,
"available_slots": null,
"status": "CLOSED",
"created_at": "2026-05-26T10:00:00.000Z",
"updated_at": "2026-05-26T12:00:00.000Z"
}
}
To re-enable a disabled window, use PATCH /{slot_id} with { "status": "OPEN" }.
Error Codes
| Status | Code | Cause |
|---|---|---|
400 | VALIDATION_ERROR | Missing required field, or ai_slots exceeds max_slots |
404 | NOT_FOUND | Slot not found |
403 | INSUFFICIENT_SCOPE | API key does not have the required scope |