> ## Documentation Index
> Fetch the complete documentation index at: https://bluebubbles.anmho.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Schedule iMessages with the BlueBubbles SDK

> Schedule iMessages for future one-time delivery or on a recurring cadence — hourly, daily, weekly, monthly, or yearly — with full CRUD support.

The BlueBubbles SDK lets you schedule messages to be sent once at a specific future time, or repeatedly on an hourly, daily, weekly, monthly, or yearly cadence. All scheduling operations live on `client.messages` and communicate with the server's built-in scheduler. Once registered, the server handles delivery autonomously — your app doesn't need to stay connected.

<Note>
  Scheduled messages require **BlueBubbles Server 1.4.0 or later**. Upgrade your server before using any of the methods in this guide.
</Note>

***

## Schedule a one-time message

Use `scheduleAMessage()` to queue a message for delivery at a specific future timestamp. Set `schedule.type` to `"once"` and provide a milliseconds-since-epoch value in `scheduledFor`.

```typescript theme={null}
import { BlueBubblesClient } from "bluebubbles-sdk";

const client = new BlueBubblesClient({
  BASE: "http://your-server:1234",
  PASSWORD: "your-server-password",
});

// Schedule a message for 9:00 AM on November 14, 2024
const sendAt = new Date("2024-11-14T09:00:00").getTime();

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;-;+15551234567",
      message: "Good morning! Don't forget our call at 10.",
      method: "private-api",
    },
    scheduledFor: sendAt,
    schedule: {
      type: "once",
    },
  },
});
```

<Note>
  If a one-time scheduled message is missed — for example because the BlueBubbles Server was offline at the scheduled time — **the message will not be sent**. It will not be retried. Use recurring schedules if reliability across restarts matters for your use case.
</Note>

### Request body fields

| Field          | Type   | Description                                                                                 |
| -------------- | ------ | ------------------------------------------------------------------------------------------- |
| `type`         | string | Action type. Always `"send-message"`                                                        |
| `payload`      | object | Message parameters, mirroring the `sendText()` body (`chatGuid`, `message`, `method`, etc.) |
| `scheduledFor` | number | Delivery time as milliseconds since Unix epoch. Must be in the future                       |
| `schedule`     | object | Scheduling configuration. For one-time: `{ "type": "once" }`                                |

***

## Schedule a recurring message

Set `schedule.type` to `"recurring"` and add `intervalType` and `interval` to repeat the message on a defined cadence.

```typescript theme={null}
// Send "Good morning!" every day at 8:00 AM, starting tomorrow
const firstSend = new Date();
firstSend.setDate(firstSend.getDate() + 1);
firstSend.setHours(8, 0, 0, 0);

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;-;+15551234567",
      message: "Good morning!",
      method: "private-api",
    },
    scheduledFor: firstSend.getTime(),
    schedule: {
      type: "recurring",
      intervalType: "daily",
      interval: 1,
    },
  },
});
```

### Recurring schedule fields

| Field          | Type   | Description                                                                           |
| -------------- | ------ | ------------------------------------------------------------------------------------- |
| `type`         | string | `"recurring"`                                                                         |
| `intervalType` | string | How to measure the interval. One of: `hourly`, `daily`, `weekly`, `monthly`, `yearly` |
| `interval`     | number | How many units between sends. `1` means every day, `2` means every other day, etc.    |

### Interval type examples

| `intervalType` | `interval` | Behavior      |
| -------------- | ---------- | ------------- |
| `hourly`       | `2`        | Every 2 hours |
| `daily`        | `1`        | Every day     |
| `weekly`       | `2`        | Every 2 weeks |
| `monthly`      | `1`        | Every month   |
| `yearly`       | `1`        | Every year    |

<Note>
  When a recurring message fires, the server calculates the next scheduled time **before** sending the current message. This keeps the cadence consistent even if delivery takes a moment. If a recurring message is missed because the server was offline, **it will not be sent for that interval** — the next fire time is rescheduled to the next occurrence in the future.
</Note>

***

## List all scheduled messages

`getScheduledMessages()` returns all scheduled messages, including past ones. Use this to display pending schedules or audit delivery history.

```typescript theme={null}
const scheduled = await client.messages.getScheduledMessages();
console.log(scheduled.data); // Array of scheduled message objects
```

***

## Fetch a single scheduled message

Use `getScheduledMessageById()` to retrieve the details of one specific scheduled message by its numeric ID:

```typescript theme={null}
const schedule = await client.messages.getScheduledMessageById({
  id: "42",
});

console.log(schedule.data.scheduledFor); // The next delivery timestamp
console.log(schedule.data.schedule);     // The schedule configuration
```

***

## Update a scheduled message

`updateAScheduledMessageById()` replaces the payload or timing of an existing scheduled message. Pass the same request body shape as `scheduleAMessage()`:

<Tabs>
  <Tab title="Update a one-time message">
    ```typescript theme={null}
    const newTime = new Date("2024-12-01T10:00:00").getTime();

    await client.messages.updateAScheduledMessageById({
      id: "42",
      requestBody: {
        type: "send-message",
        payload: {
          chatGuid: "iMessage;-;+15551234567",
          message: "Updated: our call moved to 11 AM.",
          method: "private-api",
        },
        scheduledFor: newTime,
        schedule: {
          type: "once",
        },
      },
    });
    ```
  </Tab>

  <Tab title="Update a recurring message">
    ```typescript theme={null}
    await client.messages.updateAScheduledMessageById({
      id: "7",
      requestBody: {
        type: "send-message",
        payload: {
          chatGuid: "iMessage;-;+15551234567",
          message: "Weekly check-in — how's everyone doing?",
          method: "private-api",
        },
        scheduledFor: new Date("2024-11-18T09:00:00").getTime(),
        schedule: {
          type: "recurring",
          intervalType: "weekly",
          interval: 1,
        },
      },
    });
    ```
  </Tab>
</Tabs>

***

## Delete a scheduled message

Use `deleteScheduledMessageById()` to cancel and remove a scheduled message before it fires:

```typescript theme={null}
await client.messages.deleteScheduledMessageById({
  id: "42",
});
```

Once deleted, the message will not be sent. There is no way to restore a deleted schedule — create a new one with `scheduleAMessage()` if needed.

***

## Full example: morning standup reminder

This example schedules a daily 9 AM standup reminder in a group chat, then verifies the schedule was created:

```typescript theme={null}
import { BlueBubblesClient } from "bluebubbles-sdk";

const client = new BlueBubblesClient({
  BASE: "http://your-server:1234",
  PASSWORD: "your-server-password",
});

// First send: next Monday at 9:00 AM
const nextMonday = new Date();
nextMonday.setDate(nextMonday.getDate() + ((1 + 7 - nextMonday.getDay()) % 7));
nextMonday.setHours(9, 0, 0, 0);

await client.messages.scheduleAMessage({
  requestBody: {
    type: "send-message",
    payload: {
      chatGuid: "iMessage;+;group-chat-guid",
      message: "Good morning team! Standup in 5 minutes. 🚀",
      method: "apple-script",
    },
    scheduledFor: nextMonday.getTime(),
    schedule: {
      type: "recurring",
      intervalType: "weekly",
      interval: 1,
    },
  },
});

// Confirm it was created
const all = await client.messages.getScheduledMessages();
console.log(`${all.data.length} message(s) scheduled.`);
```
