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 with 422, 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 a 422 that 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_at were 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 the scheduled_at it 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

cURL
{ "cancel": true }

or

cURL
{ "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.

Frequently asked questions

How far ahead can an AI agent schedule an email?

Up to 90 days. A later time is refused with 422. A time in the past, or within about 30 seconds, sends immediately, as if no time was given.

What happens if the agent sends a time without a timezone?

Unitpost refuses it with 422 and sends nothing. A zoneless time is the most common scheduling bug in agents, because the model assumes a timezone the server can't know.

Can a scheduled send be cancelled?

Yes. PATCH /email/{id} with {"cancel": true} cancels a scheduled or queued email, and {"scheduled_at": ...} moves a scheduled one. A batch sent with one scheduled_at is cancelled as a whole with POST /email/batches/{id}/cancel.

Send email your users actually receive

5,000 emails a month free — API, SMTP, templates, tracking. No credit card.