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

StatusDescription
pendingReminder is scheduled and waiting
sentReminder has been delivered
cancelledReminder was cancelled
snoozedReminder 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

StatusDescription
scheduledMessage is queued for sending
sentMessage was successfully sent
cancelledMessage was cancelled before sending
failedMessage 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

StatusDescription
onlineAgent is available and active
awayAgent is temporarily away
busyAgent is busy/do not disturb
offlineAgent 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 offline after 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

CodeDescription
NOT_FOUNDReminder, message, or schedule not found
FORBIDDENCannot modify another user's items
BAD_REQUESTInvalid time format or schedule configuration
TOO_MANY_REQUESTSHeartbeat rate limit exceeded