Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions fern/pages/guides/sending-receiving-email.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,47 @@ client.inboxes.messages.send(
)
```

## Scheduled sending

You can schedule an email to be sent at a future time by passing the `send_at` parameter when creating a `Draft`. This is useful for timing outreach during a recipient's business hours or spacing out follow-up sequences.

When you provide `send_at`, the `Draft` is automatically sent at the specified time — no need to call the send endpoint separately. You can track the delivery status using the `send_status` field on the `Draft`, which will be `scheduled`, `sending`, or `failed`.

<CodeBlocks>
```python
from datetime import datetime

# schedule a draft to send tomorrow at 9am UTC
draft = client.inboxes.drafts.create(
inbox_id="outreach@agentmail.to",
to=["recipient@example.com"],
subject="Quick question about your garden",
text="Hi, I wanted to follow up on the seedling order.",
html="<p>Hi, I wanted to follow up on the seedling order.</p>",
send_at=datetime(2026, 3, 5, 9, 0, 0),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The Python scheduled-send example uses a timezone-naive datetime while documenting UTC, which can schedule at the wrong time if interpreted in local/default timezone. Use an explicitly UTC timestamp.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At fern/pages/guides/sending-receiving-email.mdx, line 45:

<comment>The Python scheduled-send example uses a timezone-naive `datetime` while documenting UTC, which can schedule at the wrong time if interpreted in local/default timezone. Use an explicitly UTC timestamp.</comment>

<file context>
@@ -25,6 +25,47 @@ client.inboxes.messages.send(
+    subject="Quick question about your garden",
+    text="Hi, I wanted to follow up on the seedling order.",
+    html="<p>Hi, I wanted to follow up on the seedling order.</p>",
+    send_at=datetime(2026, 3, 5, 9, 0, 0),
+)
+
</file context>
Suggested change
send_at=datetime(2026, 3, 5, 9, 0, 0),
send_at=datetime.fromisoformat("2026-03-05T09:00:00+00:00"),
Fix with Cubic

)

print(f"Draft {draft.draft_id} scheduled, status: {draft.send_status}")
```
```typescript
// schedule a draft to send tomorrow at 9am UTC
const draft = await client.inboxes.drafts.create(
"outreach@agentmail.to",
{
to: ["recipient@example.com"],
subject: "Quick question about your garden",
text: "Hi, I wanted to follow up on the seedling order.",
html: "<p>Hi, I wanted to follow up on the seedling order.</p>",
sendAt: new Date("2026-03-05T09:00:00Z"),
}
);

console.log(`Draft ${draft.draftId} scheduled, status: ${draft.sendStatus}`);
```
</CodeBlocks>

To cancel a scheduled send, delete the `Draft` before the `send_at` time. To reschedule, update the `Draft` with a new `send_at` value.

## The Conversational Loop

A common task for an agent is to check for replies in an `Inbox` and then respond to them. While using `Webhooks` is the most efficient method for this, you can also build a simple polling mechanism.
Expand Down