API Reference
Complete API reference for Calendar endpoints.
Authentication
All Calendar API endpoints require authentication:
Authorization: Bearer YOUR_API_KEYOr use the X-API-Key header:
X-API-Key: YOUR_API_KEYBase URL
https://api.usetransactional.com/calendar
Event Types
Create Event Type
POST /calendar/event-typesBody:
{
"title": "Product Demo",
"slug": "demo",
"duration": 30,
"description": "See our product in action",
"location": {
"type": "GOOGLE_MEET"
},
"scheduleId": "schedule_xxx",
"bufferBefore": 5,
"bufferAfter": 10,
"minimumNotice": 60,
"maximumAdvance": 60
}List Event Types
GET /calendar/event-typesGet Event Type
GET /calendar/event-types/{eventTypeId}Update Event Type
PATCH /calendar/event-types/{eventTypeId}Delete Event Type
DELETE /calendar/event-types/{eventTypeId}Schedules
Create Schedule
POST /calendar/schedulesBody:
{
"name": "Work Hours",
"timezone": "America/New_York",
"isDefault": true,
"availability": [
{ "day": "MONDAY", "startTime": "09:00", "endTime": "17:00" },
{ "day": "TUESDAY", "startTime": "09:00", "endTime": "17:00" },
{ "day": "WEDNESDAY", "startTime": "09:00", "endTime": "17:00" },
{ "day": "THURSDAY", "startTime": "09:00", "endTime": "17:00" },
{ "day": "FRIDAY", "startTime": "09:00", "endTime": "17:00" }
]
}List Schedules
GET /calendar/schedulesGet Schedule
GET /calendar/schedules/{scheduleId}Update Schedule
PATCH /calendar/schedules/{scheduleId}Delete Schedule
DELETE /calendar/schedules/{scheduleId}Add Date Override
POST /calendar/schedules/{scheduleId}/overridesBody:
{
"date": "2024-12-25",
"isAvailable": false,
"reason": "Christmas Day"
}Remove Date Override
DELETE /calendar/schedules/{scheduleId}/overrides/{overrideId}Availability
Get Available Slots
GET /calendar/availabilityQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
eventTypeId | string | Event type ID (required) |
startDate | string | Start date (YYYY-MM-DD) |
endDate | string | End date (YYYY-MM-DD) |
timezone | string | Response timezone |
hostId | string | Filter by specific host |
duration | number | For multi-duration events |
Response:
{
"days": [
{
"date": "2024-01-15",
"slots": [
{ "startTime": "09:00", "endTime": "09:30" },
{ "startTime": "09:30", "endTime": "10:00" }
]
}
]
}Bookings
Create Booking
POST /calendar/bookingsBody:
{
"eventTypeId": "evt_xxx",
"startTime": "2024-01-15T10:00:00-05:00",
"attendee": {
"name": "John Doe",
"email": "john@example.com",
"timezone": "America/New_York"
},
"notes": "Looking forward to the meeting",
"responses": {
"company": "Acme Corp"
},
"metadata": {
"source": "website"
}
}Response:
{
"uid": "booking_xxx",
"eventTypeId": "evt_xxx",
"status": "CONFIRMED",
"startTime": "2024-01-15T15:00:00.000Z",
"endTime": "2024-01-15T15:30:00.000Z",
"attendee": {
"name": "John Doe",
"email": "john@example.com",
"timezone": "America/New_York"
},
"host": {
"id": "user_xxx",
"name": "Jane Smith",
"email": "jane@company.com"
},
"meetingUrl": "https://meet.google.com/xxx",
"rescheduleUrl": "https://calendar.usetransactional.com/reschedule/xxx",
"cancelUrl": "https://calendar.usetransactional.com/cancel/xxx"
}List Bookings
GET /calendar/bookingsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
count | number | Results per page (max 100) |
offset | number | Pagination offset |
status | string | Filter by status |
startDate | string | Filter by date range start |
endDate | string | Filter by date range end |
eventTypeId | string | Filter by event type |
attendeeEmail | string | Filter by attendee |
Get Booking
GET /calendar/bookings/{bookingUid}Cancel Booking
POST /calendar/bookings/{bookingUid}/cancelBody:
{
"reason": "Schedule conflict",
"cancelledBy": "attendee",
"notifyHost": true
}Reschedule Booking
POST /calendar/bookings/{bookingUid}/rescheduleBody:
{
"startTime": "2024-01-20T14:00:00-05:00",
"reason": "Need to move to next week",
"notifyAttendee": true
}Confirm Booking
POST /calendar/bookings/{bookingUid}/confirmReject Booking
POST /calendar/bookings/{bookingUid}/rejectBody:
{
"reason": "Not available at this time"
}Webhooks
Create Webhook
POST /calendar/webhooksBody:
{
"url": "https://yourapp.com/webhooks/calendar",
"events": ["booking.created", "booking.cancelled"]
}List Webhooks
GET /calendar/webhooksGet Webhook
GET /calendar/webhooks/{webhookId}Update Webhook
PATCH /calendar/webhooks/{webhookId}Delete Webhook
DELETE /calendar/webhooks/{webhookId}List Deliveries
GET /calendar/webhooks/{webhookId}/deliveriesSDK Reference
TypeScript SDK
import { Transactional } from '@usetransactional/node';
const client = new Transactional({
apiKey: process.env.TRANSACTIONAL_API_KEY,
});
// Event Types
const eventType = await client.calendar.eventTypes.create({ title, slug, duration });
const eventTypes = await client.calendar.eventTypes.list();
await client.calendar.eventTypes.update(id, { title });
await client.calendar.eventTypes.delete(id);
// Schedules
const schedule = await client.calendar.schedules.create({ name, timezone, availability });
const schedules = await client.calendar.schedules.list();
await client.calendar.schedules.update(id, { availability });
await client.calendar.schedules.addOverride(id, { date, isAvailable });
// Availability
const slots = await client.calendar.availability.get({
eventTypeId,
startDate,
endDate,
});
// Bookings
const booking = await client.calendar.bookings.create({
eventTypeId,
startTime,
attendee,
});
const bookings = await client.calendar.bookings.list({ status: 'CONFIRMED' });
await client.calendar.bookings.cancel(uid, { reason });
await client.calendar.bookings.reschedule(uid, { startTime });
// Webhooks
const webhook = await client.calendar.webhooks.create({ url, events });Python SDK
from usetransactional import Transactional
client = Transactional(api_key="your_api_key")
# Event Types
event_type = client.calendar.event_types.create(title=title, slug=slug, duration=duration)
event_types = client.calendar.event_types.list()
client.calendar.event_types.update(id, title=title)
client.calendar.event_types.delete(id)
# Schedules
schedule = client.calendar.schedules.create(
name=name,
timezone=timezone,
availability=availability
)
# Availability
slots = client.calendar.availability.get(
event_type_id=event_type_id,
start_date=start_date,
end_date=end_date
)
# Bookings
booking = client.calendar.bookings.create(
event_type_id=event_type_id,
start_time=start_time,
attendee=attendee
)
client.calendar.bookings.cancel(uid, reason=reason)
client.calendar.bookings.reschedule(uid, start_time=new_time)
# Webhooks
webhook = client.calendar.webhooks.create(url=url, events=events)Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST | Invalid request body |
| 401 | UNAUTHORIZED | Invalid or missing API key |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource not found |
| 409 | CONFLICT | Booking conflict |
| 429 | RATE_LIMITED | Too many requests |
Calendar-Specific Errors
| Code | Description |
|---|---|
SLOT_UNAVAILABLE | Time slot no longer available |
PAST_BOOKING | Cannot book in the past |
MINIMUM_NOTICE | Booking too close to start time |
MAXIMUM_ADVANCE | Booking too far in advance |
DAILY_LIMIT | Daily booking limit reached |
INVALID_TIMEZONE | Invalid timezone specified |
HOST_UNAVAILABLE | Selected host not available |
EVENT_TYPE_INACTIVE | Event type is disabled |
On This Page
- Authentication
- Base URL
- Event Types
- Create Event Type
- List Event Types
- Get Event Type
- Update Event Type
- Delete Event Type
- Schedules
- Create Schedule
- List Schedules
- Get Schedule
- Update Schedule
- Delete Schedule
- Add Date Override
- Remove Date Override
- Availability
- Get Available Slots
- Bookings
- Create Booking
- List Bookings
- Get Booking
- Cancel Booking
- Reschedule Booking
- Confirm Booking
- Reject Booking
- Webhooks
- Create Webhook
- List Webhooks
- Get Webhook
- Update Webhook
- Delete Webhook
- List Deliveries
- SDK Reference
- TypeScript SDK
- Python SDK
- Error Codes
- Calendar-Specific Errors