Overview
Add a send_at parameter to your email requests to schedule delivery at a specific time. Scheduled emails sit in a holding queue and are promoted to the send pipeline when the scheduled time arrives. You can cancel a scheduled email before its send time and get the quota refunded.
Scheduling an Email
Include send_at in the request body of POST /v1/emails. The value must be an ISO 8601 timestamp in UTC:
curl -X POST https://api.euromail.dev/v1/emails \
-H "X-EuroMail-Api-Key: em_live_..." \
-H "Content-Type: application/json" \
-d '{
"from": "[email protected]",
"to": "[email protected]",
"subject": "Your weekly digest",
"html_body": "<h1>This week in review</h1><p>...</p>",
"send_at": "2026-03-22T09:00:00Z"
}'
Response (202 Accepted):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "<[email protected]>",
"status": "scheduled",
"to": "[email protected]",
"sandbox": false,
"scheduled_at": "2026-03-22T09:00:00Z",
"created_at": "2026-03-21T14:00:00Z"
}
When send_at is provided, the response returns status: "scheduled" and includes a scheduled_at field echoing the scheduled time.
Constraints
| Rule | Detail |
|---|---|
| Must be future | send_at must be later than the current time |
| Maximum 30 days ahead | send_at cannot be more than 30 days in the future |
| Format | ISO 8601 / RFC 3339 in UTC (e.g. 2026-03-22T09:00:00Z) |
Requests that violate these constraints return 400 Bad Request:
{
"error": "send_at must be a future timestamp"
}{
"error": "send_at must be within 30 days from now"
}Cancelling a Scheduled Email
Cancel a scheduled email before its send time:
curl -X POST https://api.euromail.dev/v1/emails/{id}/cancel \
-H "X-EuroMail-Api-Key: em_live_..."
Response (200 OK):
The response returns the email with status: "failed" and an error message indicating cancellation:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"error_message": "cancelled by user before scheduled send time"
}
}
Only emails with status: "scheduled" can be cancelled. If the email has already been promoted to the send queue (status is "queued" or later), the cancel request returns 404 Not Found.
Status Flow
┌──────────┐ cancel ┌────────┐
│scheduled │───────────────►│ failed │
└────┬─────┘ └────────┘
│
│ send_at time arrives
▼
┌──────────┐
│ queued │
└────┬─────┘
│
▼
┌──────────┐
│ sent │──► delivered / bounced / failed
└──────────┘
- scheduled -- Email is waiting for the scheduled time. Can be cancelled.
- queued -- The schedule checker has promoted the email to the send queue. Processing begins.
- sent -- Email has been handed off to the recipient's mail server.
- delivered / bounced / failed -- Final delivery outcome.
The schedule checker runs every second and promotes all emails whose send_at time has passed.
Quota
Quota is consumed immediately when you schedule an email, not when it is sent. This reserves capacity and prevents over-scheduling.
If you cancel a scheduled email, the quota is refunded automatically.
| Action | Quota Effect |
|---|---|
| Schedule email | Quota decremented |
| Cancel scheduled email | Quota refunded |
| Email sent successfully | No additional change (already consumed) |
Attachments
Attachments are fully supported with scheduled emails. When you include attachments in a scheduled email, the file contents are persisted in the database (not just in the send queue) so they are available when the email is promoted for sending. There is no difference in attachment size limits between immediate and scheduled emails.
Idempotency
Idempotency keys work with scheduled emails. If you send the same request with the same idempotency_key, the API returns the original response without creating a duplicate scheduled email.
Validation
All validation happens at schedule time, not at send time:
- Sender address must belong to a verified domain
- Recipient address must pass syntax validation
- Template (if using
template_alias) must exist and render successfully - Quota must be available
- Attachments must be valid base64 with allowed content types
If any validation fails, the request is rejected immediately. You will not discover validation errors at send time.
Dashboard
Scheduled emails appear in the email list with an amber status badge. The email detail page shows the scheduled delivery time. You can filter the email list to show only scheduled emails.