How to schedule email and texts from an AI agent
Have the agent pass scheduled_at as an ISO 8601 time with its offset, such as 2026-11-20T09:00:00-05:00, never a bare local time: Unitpost refuses a time without a zone, reads every time back in UTC, and schedules up to 90 days ahead. The agent cancels or moves a send with PATCH /email/{id}, and marketing texts also wait for the recipient's quiet hours to end.
Unitpost ·
"Send this Friday at 9" is easy for a person and ambiguous for an agent: whose Friday, and whose 9? Most scheduling bugs in agents are timezone bugs, and an email API can catch them only if it refuses what's ambiguous.
How should the agent write the time?
As ISO 8601 with a zone: 2026-11-20T09:00:00-05:00 or 2026-11-20T14:00:00Z. On Unitpost:
- a time without a zone (
2026-11-20T09:00:00) is refused with422, and nothing is sent; - an offset is accepted and normalized, and every read returns UTC;
- the field is
scheduled_at. A misnamed field (send_at,sendAt) is refused with a422that names it, so a model's guess never turns into an immediate send.
Give the agent the recipient's timezone as data, from the contact or the request, and tell it to convert, not assume. "The customer is in America/New_York; schedule for 9:00 their time" leaves one right answer.
What are the limits?
- Horizon: up to 90 days ahead; further is refused.
- Past times: a time in the past, or within about 30 seconds, sends at once, as if
scheduled_atwere missing. If the agent meant tomorrow and wrote today, the mail goes now, so have it read back the time before it schedules. - Status: a scheduled send answers
status: "scheduled"with thescheduled_atit will use. Have the agent read that back to the person in their timezone.
How does the agent cancel or move a send?
One endpoint does both: PATCH /email/{id} with exactly one of
{ "cancel": true }or
{ "scheduled_at": "2026-11-21T09:00:00-05:00" }Cancel works on scheduled and queued emails. A batch scheduled with one scheduled_at is cancelled together with POST /email/batches/{id}/cancel. Over MCP the same operations are tools, so "move Friday's reminder to Monday" is a lookup and one call.
What changes for texts?
Texts take the same scheduled_at. Marketing texts also respect the recipient's local quiet hours (8:00 to 21:00, narrower where a law or an operator code requires): a marketing text due outside them waits, and the sms.scheduled event says quiet_hours_deferred. Appointment reminders and other texts a person asked for aren't held (reminders from an agent).
Who confirms the schedule?
For one person's reminder, the agent can schedule and report. For anything one-to-many, a campaign or a batch, have it propose the time and the audience, and let a person approve before it calls send (approval before send). A scheduled mistake is cancellable until it fires, which is a good reason to schedule big sends a little ahead rather than send them now.