Graine AI

The scheduled-calls list

Book, list and cancel the user's calls from your own screens: the booking rules and their checks on the device, scheduleCall, scheduledCalls and cancelScheduledCall, every status a call moves through, who booked it, and the chat's upcoming-calls card — on every platform.

Every booked call — by the agent in a conversation, by the user from your app, by your team in the dashboard — is one list per user. Your app can read it, cancel from it, and book into it with a screen of its own (or let the SDK's sheet do the booking).

What it needs in the dashboard

WhereSettingValue
Agent → Calls & scheduling → Who may book a callUsers, from your appOn — and its three limits
Agent → Calls & scheduling → Who may book a callThe agent, during a conversationOn, for "call me tomorrow at 6" in a conversation
Agent → Calling WindowThe agent's hoursApplied in the user's own time zone
Agent → Calls & scheduling → Scheduled calls—Your team's view of every call, and Schedule a call

What to do, in order

  1. Read the rules — schedulingRules: whether users may book, the earliest and latest times (earliest(now), latest(now)), how many may wait, the call name. No request: it comes with the agent's settings.
  2. Book with a time and an optional reason (120 characters). → The SDK refuses on the device first — scheduling_off, too_soon, too_far — then Graine checks the calling window and the calls already waiting.
  3. List the user's calls — upcoming first.
  4. Cancel one whose canCancel is true. → Its status becomes cancelled.
  5. Follow the status as the time comes: scheduled → ringing → answered → completed, or declined, missed, failed, expired, no_device.
StatusMeans
scheduledBooked; nothing has rung yet. canCancel is true
ringingThe phone is ringing now
answered, completedThe user answered; the conversation is over
declinedThe user declined. Nothing rings them again for 6 hours
missedNobody answered. One more ring after your delay, if set
failedIt could not ring or connect
cancelledCalled off before it rang
expiredMore than 10 minutes late (held by quiet hours or the window), or no opening left
no_deviceNo app device of the user's seen in the last 30 days — a browser cannot ring

source says who booked it: agent, app (your app), dashboard or api. A status or source newer than your SDK arrives as unknown, carrying its word.

The code, platform by platform

let graine = GraineInApp.shared
let rules = graine.schedulingRules                                    // 1
guard rules.usersCanBook else { return }
let inAnHour = max(rules.earliest(now: Date()), Date().addingTimeInterval(3600))
 
do {
    let call = try await graine.scheduleCall(at: inAnHour, reason: "Talk through my order")   // 2
    let upcoming: [GraineScheduledCall] = try await graine.scheduledCalls()                  // 3
    print(upcoming.map { "\($0.id) \($0.status) \($0.source?.description ?? "")" })
    if call.canCancel {
        let status = try await graine.cancelScheduledCall(id: call.id)                        // 4: .cancelled
        print(status)
    }
} catch let error as GraineServiceError {
    switch error.code {
    case .tooSoon, .tooFar, .outsideWindow: print("Pick another time: \(error.message)")
    case .tooManyPending: print("Cancel one first")
    default: print(error.code, error.message)
    }
}

The chat's card, for a screen of yours: graine.chat.upcomingCalls (published), chat.refreshUpcomingCalls(), chat.cancelUpcomingCall(id:).

Troubleshooting

What you seeWhyFix
scheduling_off before any requestUsers, from your app is off, or the settings have not loadedTurn it on; wait for the settings
too_soon / too_farOutside earliest(now) … latest(now)Offer only times in that range
outside_windowOutside the agent's Calling Window in the user's time zoneThe message names a time that works
too_many_pendingThe user has the most calls waitingCancel one first
rate_limitedMore than 10 bookings in an hour from one installWait retryAfterSeconds
A call ended no_deviceThe user has no app device seen in 30 daysThey open the app signed in, once

The full rules, holds and webhooks: Scheduled calls · SDK reference → Scheduling.

On this page