---
title: "Send scheduled notifications"
description: "Schedule notifications to multiple customers for future delivery using the Chime scheduling API."
canonical: "https://studio.inttegro.com/guides/send-scheduled-notifications"
format: inttegro-machine-docs/v1
language: "Python"
sdk_version: "v12.0.0"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/python/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 573
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "curated"
recommended_mcp_tools: ["get_message","list_messages"]
estimated_tokens: 3445
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** A scheduled Chime is accepted now and becomes delivery-eligible later; retain the schedule ID, check execution, and inspect each resulting Chime for actual delivery.

### Five questions

#### Q1. What is the trust boundary for recipients?

Use one transport per schedule. Inline recipients need a matching phone or email shape; saved customers need a customer ID and transport. A malformed or unresolved recipient rejects the entire request. Follow [Schedule chime](https://studio.inttegro.com/machine/python/api/chimes.md#schedule-chime) for exact selected-language fields.

#### Q2. Does a schedule response mean messages were delivered?

No. It returns a schedule ID before its future execution. [Lookup a scheduled chime](https://studio.inttegro.com/machine/python/api/chimes.md#lookup-a-scheduled-chime) for resulting Chime IDs and per-recipient errors, then [lookup each Chime](https://studio.inttegro.com/machine/python/api/chimes.md#lookup-chime) for delivery state.

#### Q3. Is send_after an exact delivery guarantee?

No. It is the time the schedule becomes eligible; provider and recipient-network delays can follow. Use immediate Chimes for time-critical communication and the OTP API—not Chimes—for verification codes.

#### Q4. Can a scheduled batch be changed or canceled after execution?

Cancel only while pending, before execution; afterward preserve the individual delivery records. For corrected content or audience, cancel the pending schedule and create a new one with a stable [idempotency policy](https://studio.inttegro.com/machine/python/api/idempotency.md). See [cancel a scheduled chime](https://studio.inttegro.com/machine/python/api/chimes.md#cancel-a-scheduled-chime).

#### Q5. Which MCP and SDK paths fit?

The catalog has [list_messages](https://studio.inttegro.com/machine/python/inttegro-mcp/tools.md#list_messages) and [get_message](https://studio.inttegro.com/machine/python/inttegro-mcp/tools.md#get_message) for resulting Chimes, but no scheduling or cancellation action. This guide's language tabs include direct HTTP examples; use the [Chimes reference](https://studio.inttegro.com/machine/python/api/chimes.md#schedule-chime) for verified native SDK parameters instead of copying wire JSON into an SDK call.

## Document content

# Send scheduled notifications

Schedule notifications to reach customers at specific future times—subscription renewal reminders, appointment confirmations, promotional campaigns, or payment due dates. Send to one recipient or broadcast to thousands with a single API call. Messages deliver at or shortly after the scheduled time without requiring you to maintain background workers or cron jobs.

> Mcp Guide Callout is interactive content. Use the canonical page to view it.

> **Note:**
>
> **Don't use Chimes for verification codes.** If you need to authenticate or
> verify users with one-time passwords, use the [OTP API](https://studio.inttegro.com/machine/python/api/otps.md) instead. The
> OTP API handles token generation, expiry, validation, and rate
> limiting—critical security features that Chimes doesn't provide. See [Verify
> customers with OTP](https://studio.inttegro.com/machine/python/guides/verify-with-otp.md) to learn how to implement secure
> authentication flows.

## How scheduling works

Scheduled Chimes become eligible for delivery at a future timestamp you specify. One schedule can reach one or many recipients. The API resolves saved customers and validates every inline phone number or email address before accepting the request. A malformed or unresolved recipient rejects the entire schedule; later transmission failures remain isolated to the affected recipient.

Recipients receive messages through SMS or email. Inline recipients use `recipients[].type` plus a matching `recipients[].phone.number` or `recipients[].email.address`; saved-customer recipients use `recipients[].transport` plus `recipients[].customer_id`. All recipients in a single schedule must resolve to the same transport, so create separate schedules when a campaign needs both SMS and email delivery.

Put the message body in [`full_message`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#ChimeRequest.full_message) and keep every recipient on the same transport. Create separate schedules when a campaign needs both SMS and email delivery. Email content is safety-scanned before the schedule is accepted.

```python
inttegro.schedule.ChimeRequest(
  recipients=[
    inttegro.chime.InlineRecipientInputVariant1(),
  ],
  full_message="Your subscription renews tomorrow. Update billing at https://yourstore.example/billing.",
  send_after=datetime.fromisoformat("2030-12-17T09:00:00Z".replace("Z", "+00:00")),
  sender_id="YourStore",
  purpose="subscription_reminder",
)
```

## Schedule a notification

Call [Schedule Chimes](https://studio.inttegro.com/machine/python/api/chimes.md#post-chimes-schedule) with your message content, recipient list, and delivery timestamp. The API returns a schedule ID immediately—actual delivery happens at the specified time.

**Schedule notification — POST /chimes/schedule**

```python
import os
from datetime import datetime

import inttegro
from inttegro import InttegroClient

client = InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])

result = client.chimes.schedule(inttegro.schedule.ChimeRequest(
  recipients=[
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233544998605",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233501234567",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233208765432",
      ),
    ),
  ],
  full_message="Reminder: Your subscription renews tomorrow on Dec 18. Update payment method at https://pages.inttegro.com/invoices/billing if needed or contact support.",
  send_after=datetime.fromisoformat("2030-12-17T09:00:00Z".replace("Z", "+00:00")),
  sender_id="YourBrand",
  purpose="subscription_reminder",
  request_meta=inttegro.schedule.ChimeRequestRequestMeta(
    idempotency_key="sched_renewal_batch_dec_2025",
  ),
))
```

The response confirms your schedule with an ID, recipient count, send time, and creation timestamp. Store the schedule ID if you need to track delivery later or reconcile sent messages with your records.

## Recipient validation

Inttegro resolves and validates every recipient during request processing. Inline phone and email contacts must be well formed, while saved-customer references must exist and contain a valid contact for the selected transport. If any recipient fails these checks, correct the recipient and submit the schedule again.

Acceptance does not guarantee later delivery. After execution, transmission failures are recorded per recipient and do not change whether the other accepted recipients can be sent.

## Delivery timing

[`send_after`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#ChimeRequest.send_after) controls when a schedule becomes eligible to execute; it is not a delivery-time
guarantee. Allow for processing and network delays, and do not rely on
sub-minute precision.

If you need immediate delivery, [send a Chime](https://studio.inttegro.com/machine/python/guides/send-customer-notification.md) instead. For time-critical notifications like password resets or purchase confirmations, send immediately rather than scheduling.

## Broadcast to many recipients

Schedule one message to thousands of recipients with a single API call. Each recipient receives an individual Chime—no shared message threads or group texts. Track each delivery independently through the Chime API.

**Broadcast campaign — POST /chimes/schedule**

```python
import os
from datetime import datetime

import inttegro
from inttegro import InttegroClient

client = InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])

result = client.chimes.schedule(inttegro.schedule.ChimeRequest(
  recipients=[
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233544998605",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233501234567",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233208765432",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233277654321",
      ),
    ),
    inttegro.chime.InlineRecipientInputVariant1(
      type="phone",
      phone=inttegro.chime.InlineRecipientInputVariant1Phone(
        number="+233248888888",
      ),
    ),
  ],
  full_message="Flash Sale! 30% off all items today only. Shop now: https://shop.example.com/sale Use code: FLASH30",
  send_after=datetime.fromisoformat("2030-12-17T08:00:00Z".replace("Z", "+00:00")),
  sender_id="ShopBrand",
  purpose="marketing_campaign",
))
```

The API currently enforces that [`recipients`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#Schedule) contains at least one item but does not publish a fixed maximum. Apply your own bounded batch size and monitor each schedule independently.

## Managing scheduled notifications

### Tracking execution and delivery

Check schedule status, view delivered message IDs, and identify failed recipients using [`POST /schedules/lookup`](https://studio.inttegro.com/machine/python/api/chimes.md#lookup-a-scheduled-chime). Returns the schedule details plus IDs of all created Chimes after execution. The [`errors`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#Schedule) array includes failure reasons for any recipients that didn't receive messages.

**Track schedule status — POST /schedules/lookup**

```python
import os

from inttegro import InttegroClient

client = InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])

result = client.schedules.lookup("sch_kPvqTrqGsopu07wfC7ttoWqmfwt48ZW7BGvYUWk")
```

Before execution, [`executed_at`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail) is absent and [`chime_ids`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail) may be omitted. After execution, [`chime_ids`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail), when present, contains IDs of successfully created Chimes. Use [Lookup a Chime](https://studio.inttegro.com/machine/python/api/chimes.md#lookup-a-chime) with these IDs to check individual delivery status and transmission details. The optional [`errors`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail) array lists per-recipient execution failures.

Use this to debug broadcast campaigns: if 485 out of 500 messages delivered, the [`errors`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail) array tells you exactly which 15 recipients failed and why. Correct the invalid addresses and create a new schedule for just those recipients.

### Canceling pending schedules

Cancel schedules before execution using [`POST /schedules/cancel`](https://studio.inttegro.com/machine/python/api/chimes.md#cancel-a-scheduled-chime). Prevents delivery if called before [`send_after`](https://python.inttegro.dev/v12.0.0/inttegro/schedule.html#CancelDetail) time. Returns an error if the schedule already executed or was previously canceled.

**Cancel schedule — POST /schedules/cancel**

```python
import os

from inttegro import InttegroClient

client = InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])

result = client.schedules.cancel("sch_kPvqTrqGsopu07wfC7ttoWqmfwt48ZW7BGvYUWk")
```

Common cancellation scenarios: customer opts out of marketing before campaign sends, you discover an error in the message content, or a scheduled event gets postponed. Cancel the original schedule and create a new one with corrected details.

Cancellation only works on pending schedules. Repeating a new cancellation after the schedule is canceled returns an error.

## Next steps

- **[Chime API Reference](https://studio.inttegro.com/machine/python/api/chimes.md)** — Complete endpoint documentation including schedule lookup
- **[Send customer notifications](https://studio.inttegro.com/machine/python/guides/send-customer-notification.md)** — Send immediate notifications for real-time events
- **[Product: Chime](https://studio.inttegro.com/machine/python/products/chimes.md)** — Deep dive into Chime features and architecture
