Scheduling API
The Scheduling API manages follow-up reminders, scheduled messages, agent schedules, and agent status tracking.
Overview
The scheduling system provides:
- Follow-up Reminders: Set reminders for ticket follow-ups
- Scheduled Messages: Queue messages to send at specific times
- Agent Schedules: Define working hours and availability
- Agent Status: Track online/away/busy/offline status
Follow-up Reminders
Reminder Object
{
id: string; // UUID
organization_id: string; // UUID of the organization
ticket_id: string; // UUID of the associated ticket
user_id: string; // UUID of the user who set the reminder
remind_at: string; // ISO timestamp when reminder should fire
note?: string; // Optional note about the reminder
status: string; // pending, sent, cancelled, snoozed
sent_at?: string; // ISO timestamp when reminder was sent
snoozed_until?: string; // ISO timestamp if snoozed
created_at: string; // ISO timestamp
}
Reminder Status Values
| Status | Description |
|---|---|
pending | Reminder is scheduled and waiting |
sent | Reminder has been delivered |
cancelled | Reminder was cancelled |
snoozed | Reminder was snoozed to a later time |
List Reminders
Retrieve reminders for the current user.
Procedure: scheduling.listReminders
Authentication: Required
Input:
{
ticketId?: string; // Filter by ticket UUID
status?: string; // Filter by status
upcoming?: boolean; // Only show future reminders (default: true)
limit?: number; // 1-100, default: 50
}
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.listReminders?input=%7B%22upcoming%22:true%7D" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": [
{
"id": "uuid",
"ticket_id": "ticket-uuid",
"remind_at": "2024-01-16T09:00:00.000Z",
"note": "Follow up on billing issue",
"status": "pending",
"ticket": {
"id": "ticket-uuid",
"subject": "Billing discrepancy",
"status": "pending"
},
"created_at": "2024-01-15T10:00:00.000Z"
}
]
}
}
}
Get Reminder
Retrieve a single reminder by ID.
Procedure: scheduling.getReminder
Authentication: Required
Input:
{
id: string; // Reminder UUID
}
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.getReminder?input=%7B%22id%22:%22reminder-uuid%22%7D" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"ticket_id": "ticket-uuid",
"remind_at": "2024-01-16T09:00:00.000Z",
"note": "Follow up on billing issue",
"status": "pending",
"ticket": {
"id": "ticket-uuid",
"subject": "Billing discrepancy",
"status": "pending",
"customer": {
"name": "John Doe",
"email": "john@example.com"
}
}
}
}
}
}
Create Reminder
Create a new follow-up reminder.
Procedure: scheduling.createReminder
Authentication: Required
Input:
{
ticketId: string; // Required, ticket UUID
remindAt: string; // Required, ISO timestamp
note?: string; // Optional note (max 500 characters)
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.createReminder" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"ticketId": "ticket-uuid",
"remindAt": "2024-01-16T09:00:00.000Z",
"note": "Check if customer received refund"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"ticket_id": "ticket-uuid",
"remind_at": "2024-01-16T09:00:00.000Z",
"note": "Check if customer received refund",
"status": "pending",
"created_at": "2024-01-15T10:00:00.000Z"
}
}
}
}
Update Reminder
Update an existing reminder.
Procedure: scheduling.updateReminder
Authentication: Required
Input:
{
id: string; // Required, reminder UUID
remindAt?: string; // ISO timestamp
note?: string; // Note (max 500 characters)
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.updateReminder" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"id": "reminder-uuid",
"remindAt": "2024-01-17T14:00:00.000Z"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"remind_at": "2024-01-17T14:00:00.000Z",
"status": "pending"
}
}
}
}
Cancel Reminder
Cancel a pending reminder.
Procedure: scheduling.cancelReminder
Authentication: Required
Input:
{
id: string; // Reminder UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.cancelReminder" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"reminder-uuid"}}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"status": "cancelled"
}
}
}
}
Snooze Reminder
Snooze a reminder to a later time.
Procedure: scheduling.snoozeReminder
Authentication: Required
Input:
{
id: string; // Reminder UUID
snoozedUntil: string; // ISO timestamp for new reminder time
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.snoozeReminder" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"id": "reminder-uuid",
"snoozedUntil": "2024-01-16T15:00:00.000Z"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"status": "snoozed",
"snoozed_until": "2024-01-16T15:00:00.000Z"
}
}
}
}
Scheduled Messages
Scheduled Message Object
{
id: string; // UUID
organization_id: string; // UUID of the organization
ticket_id: string; // UUID of the associated ticket
user_id: string; // UUID of the user who scheduled
content: object; // Message content (TipTap JSON)
send_at: string; // ISO timestamp when message should send
status: string; // scheduled, sent, cancelled, failed
sent_at?: string; // ISO timestamp when actually sent
error?: string; // Error message if failed
created_at: string; // ISO timestamp
}
Scheduled Message Status Values
| Status | Description |
|---|---|
scheduled | Message is queued for sending |
sent | Message was successfully sent |
cancelled | Message was cancelled before sending |
failed | Message failed to send |
List Scheduled Messages
Retrieve scheduled messages.
Procedure: scheduling.listScheduledMessages
Authentication: Required
Input:
{
ticketId?: string; // Filter by ticket UUID
status?: string; // Filter by status
limit?: number; // 1-100, default: 50
}
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.listScheduledMessages" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": [
{
"id": "uuid",
"ticket_id": "ticket-uuid",
"content": {
"type": "doc",
"content": [{"type": "paragraph", "content": [{"type": "text", "text": "Following up..."}]}]
},
"send_at": "2024-01-16T09:00:00.000Z",
"status": "scheduled",
"ticket": {
"id": "ticket-uuid",
"subject": "Support request"
}
}
]
}
}
}
Create Scheduled Message
Schedule a message to be sent at a specific time.
Procedure: scheduling.createScheduledMessage
Authentication: Required
Input:
{
ticketId: string; // Required, ticket UUID
content: object; // Required, TipTap JSON content
sendAt: string; // Required, ISO timestamp (must be in future)
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.createScheduledMessage" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"ticketId": "ticket-uuid",
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{"type": "text", "text": "Hi, just following up on your request. Have you had a chance to try the solution I suggested?"}]
}
]
},
"sendAt": "2024-01-16T09:00:00.000Z"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"ticket_id": "ticket-uuid",
"send_at": "2024-01-16T09:00:00.000Z",
"status": "scheduled",
"created_at": "2024-01-15T10:00:00.000Z"
}
}
}
}
Update Scheduled Message
Update a scheduled message before it's sent.
Procedure: scheduling.updateScheduledMessage
Authentication: Required
Input:
{
id: string; // Required, message UUID
content?: object; // TipTap JSON content
sendAt?: string; // ISO timestamp
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.updateScheduledMessage" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"id": "message-uuid",
"sendAt": "2024-01-17T10:00:00.000Z"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"send_at": "2024-01-17T10:00:00.000Z",
"status": "scheduled"
}
}
}
}
Cancel Scheduled Message
Cancel a scheduled message.
Procedure: scheduling.cancelScheduledMessage
Authentication: Required
Input:
{
id: string; // Message UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.cancelScheduledMessage" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"message-uuid"}}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"status": "cancelled"
}
}
}
}
Send Scheduled Message Now
Send a scheduled message immediately.
Procedure: scheduling.sendScheduledMessageNow
Authentication: Required
Input:
{
id: string; // Message UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.sendScheduledMessageNow" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"message-uuid"}}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"status": "sent",
"sent_at": "2024-01-15T11:00:00.000Z"
}
}
}
}
Agent Schedules
Schedule Object
{
id: string; // UUID
organization_id: string; // UUID of the organization
user_id: string; // UUID of the agent
day_of_week: number; // 0-6 (Sunday-Saturday)
start_time: string; // HH:MM format (e.g., "09:00")
end_time: string; // HH:MM format (e.g., "17:00")
timezone: string; // IANA timezone (e.g., "America/New_York")
created_at: string; // ISO timestamp
}
Schedule Override Object
{
id: string; // UUID
user_id: string; // UUID of the agent
date: string; // YYYY-MM-DD format
start_time?: string; // HH:MM or null (day off)
end_time?: string; // HH:MM or null (day off)
reason?: string; // Optional reason
}
List Agent Schedules
List schedules for all agents in the organization.
Procedure: scheduling.listAgentSchedules
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.listAgentSchedules" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": [
{
"user": {
"id": "user-uuid",
"name": "Alice Agent",
"email": "alice@company.com"
},
"schedules": [
{"day_of_week": 1, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 2, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 3, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 4, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 5, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"}
],
"overrides": []
}
]
}
}
}
Get My Schedule
Get the current user's schedule.
Procedure: scheduling.getMySchedule
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.getMySchedule" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"schedules": [
{"day_of_week": 1, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 2, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 3, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 4, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"},
{"day_of_week": 5, "start_time": "09:00", "end_time": "17:00", "timezone": "America/New_York"}
],
"overrides": [
{"date": "2024-01-20", "start_time": null, "end_time": null, "reason": "PTO"}
],
"isCurrentlyWorking": true,
"nextShiftStart": null,
"nextShiftEnd": "2024-01-15T17:00:00.000Z"
}
}
}
}
Set Schedule
Set or update the current user's weekly schedule.
Procedure: scheduling.setSchedule
Authentication: Required
Input:
{
schedules: Array<{
dayOfWeek: number; // 0-6 (Sunday-Saturday)
startTime: string; // HH:MM format
endTime: string; // HH:MM format
}>;
timezone: string; // IANA timezone
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.setSchedule" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"schedules": [
{"dayOfWeek": 1, "startTime": "08:00", "endTime": "16:00"},
{"dayOfWeek": 2, "startTime": "08:00", "endTime": "16:00"},
{"dayOfWeek": 3, "startTime": "08:00", "endTime": "16:00"},
{"dayOfWeek": 4, "startTime": "08:00", "endTime": "16:00"},
{"dayOfWeek": 5, "startTime": "08:00", "endTime": "16:00"}
],
"timezone": "America/Los_Angeles"
}
}'
Response:
{
"result": {
"data": {
"json": {
"success": true,
"schedules": [...]
}
}
}
}
Set Bulk Schedule
Set schedules for multiple agents at once. Admin only.
Procedure: scheduling.setBulkSchedule
Authentication: Required (Admin)
Input:
{
userIds: string[]; // Array of user UUIDs
schedules: Array<{
dayOfWeek: number;
startTime: string;
endTime: string;
}>;
timezone: string;
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.setBulkSchedule" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"userIds": ["user-uuid-1", "user-uuid-2"],
"schedules": [
{"dayOfWeek": 1, "startTime": "09:00", "endTime": "17:00"},
{"dayOfWeek": 2, "startTime": "09:00", "endTime": "17:00"},
{"dayOfWeek": 3, "startTime": "09:00", "endTime": "17:00"},
{"dayOfWeek": 4, "startTime": "09:00", "endTime": "17:00"},
{"dayOfWeek": 5, "startTime": "09:00", "endTime": "17:00"}
],
"timezone": "America/New_York"
}
}'
Response:
{
"result": {
"data": {
"json": {
"success": true,
"updatedCount": 2
}
}
}
}
Add Schedule Override
Add a schedule exception (day off, different hours, etc.).
Procedure: scheduling.addScheduleOverride
Authentication: Required
Input:
{
date: string; // YYYY-MM-DD format
startTime?: string; // HH:MM or null for day off
endTime?: string; // HH:MM or null for day off
reason?: string; // Optional reason
}
Example - Day Off:
curl -X POST "https://your-domain.com/api/trpc/scheduling.addScheduleOverride" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"date": "2024-01-20",
"startTime": null,
"endTime": null,
"reason": "Personal time off"
}
}'
Example - Different Hours:
curl -X POST "https://your-domain.com/api/trpc/scheduling.addScheduleOverride" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"date": "2024-01-22",
"startTime": "10:00",
"endTime": "14:00",
"reason": "Doctor appointment in morning"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"date": "2024-01-20",
"start_time": null,
"end_time": null,
"reason": "Personal time off"
}
}
}
}
Delete Schedule
Delete a user's entire schedule. Admin only or self.
Procedure: scheduling.deleteSchedule
Authentication: Required
Input:
{
userId?: string; // User UUID (optional, defaults to current user)
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.deleteSchedule" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{}}'
Response:
{
"result": {
"data": {
"json": {
"success": true
}
}
}
}
Agent Status
Status Object
{
user_id: string; // UUID of the agent
status: string; // online, away, busy, offline
status_message?: string; // Optional status message
last_seen: string; // ISO timestamp of last activity
updated_at: string; // ISO timestamp
}
Agent Status Values
| Status | Description |
|---|---|
online | Agent is available and active |
away | Agent is temporarily away |
busy | Agent is busy/do not disturb |
offline | Agent is offline |
List Agent Status
List current status of all agents in the organization.
Procedure: scheduling.listAgentStatus
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.listAgentStatus" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": [
{
"user": {
"id": "user-uuid",
"name": "Alice Agent",
"email": "alice@company.com"
},
"status": "online",
"status_message": null,
"last_seen": "2024-01-15T10:55:00.000Z"
},
{
"user": {
"id": "user-uuid-2",
"name": "Bob Agent",
"email": "bob@company.com"
},
"status": "away",
"status_message": "At lunch",
"last_seen": "2024-01-15T10:30:00.000Z"
}
]
}
}
}
Get My Status
Get the current user's status.
Procedure: scheduling.getMyStatus
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.getMyStatus" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"status": "online",
"status_message": null,
"last_seen": "2024-01-15T10:55:00.000Z"
}
}
}
}
Set My Status
Update the current user's status.
Procedure: scheduling.setMyStatus
Authentication: Required
Input:
{
status: 'online' | 'away' | 'busy' | 'offline';
statusMessage?: string; // Optional message (max 100 characters)
}
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.setMyStatus" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"status": "away",
"statusMessage": "In a meeting until 2pm"
}
}'
Response:
{
"result": {
"data": {
"json": {
"status": "away",
"status_message": "In a meeting until 2pm",
"updated_at": "2024-01-15T11:00:00.000Z"
}
}
}
}
Heartbeat
Send a heartbeat to update last seen time and maintain online status.
Procedure: scheduling.heartbeat
Authentication: Required
Input: None
Example:
curl -X POST "https://your-domain.com/api/trpc/scheduling.heartbeat" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{}}'
Response:
{
"result": {
"data": {
"json": {
"success": true,
"last_seen": "2024-01-15T11:00:00.000Z"
}
}
}
}
Rate Limit: Minimum 30 seconds between heartbeat calls.
Notes:
- Client applications should send heartbeats every 60 seconds
- Status automatically changes to
offlineafter 5 minutes without heartbeat
Dashboard Overview
Get Overview
Get a scheduling overview including upcoming reminders and scheduled messages.
Procedure: scheduling.getOverview
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/scheduling.getOverview" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"reminders": {
"pending": 5,
"dueToday": 2,
"overdue": 0
},
"scheduledMessages": {
"scheduled": 3,
"sendingToday": 1
},
"schedule": {
"isCurrentlyWorking": true,
"nextShiftEnd": "2024-01-15T17:00:00.000Z"
},
"status": {
"current": "online",
"message": null
}
}
}
}
}
Error Codes
| Code | Description |
|---|---|
NOT_FOUND | Reminder, message, or schedule not found |
FORBIDDEN | Cannot modify another user's items |
BAD_REQUEST | Invalid time format or schedule configuration |
TOO_MANY_REQUESTS | Heartbeat rate limit exceeded |