io.input.datetime

A date and a time, the same instant everywhere.

io.input.datetime asks for a date and a time, such as when a trial ends. The person picks it in their own time zone, which is shown under the field. The handler gets a luxon DateTime in UTC. It is the same instant whatever time zone the person is in.

The simplest one

The whole action file, and roughly what your team sees when it runs.

src/actions/accounts/extendTrialAction.ts
import { DateTime } from 'luxon';
import { app } from '../../app';
export const extendTrialAction = app.defineAction({
name: 'Extend trial',
handler: async ({ io }) => {
const endsAt = await io.input.datetime('Trial ends at', {
min: DateTime.now(),
});
},
});
The code. One call in an action, the whole file.
tools.example.com/actions/accounts/extend_trial

Extend trial

Trial ends at
Nov 10, 2026, 9:00 AM
Time zone: America/New_York
Continue
In the browser. Roughly what your team sees. Your theme decides the details.

What you can set

The settings you will reach for most, each with the line of code that turns it on.

io.input.datetime('Trial ends at')

The time zone, shown. The field works in the browser’s time zone and names it under the field. Nobody has to convert in their head.

min: DateTime.now()

Earliest and latest. Set the first and last time that can be picked. The server checks every answer, to the minute.

defaultValue: '2026-11-10T14:00Z'

A starting value. Pass a luxon DateTime, a JavaScript Date or an ISO 8601 string. Without one the field starts empty.

endsAt.setZone('America/New_York')

A luxon DateTime back. It comes in UTC. Convert it with .setZone() for local time, or store it with .toISO().

io.input.datetime('Remind me at').optional()

Optional. The field is required by default. With .optional() it can stay empty and the handler gets undefined.

.validate((startsAt) => check(startsAt))

Your own check. .validate() gets the DateTime on the server. Return a message, such as one for a call outside office hours.

Write your first tool today.

An async function, a few await calls, and the form is in the browser.

AwaitIO is free for small teams, made possible by companies and people who sponsor it.