Concepts
Time zones
Moments are ISO 8601 in UTC. Where a person reads a time, the venue's wall time is beside it, with the event's time zone.
Two kinds of time
Moments are when something happened or will happen: a registration, a payment, a check-in, the start of a session. They are ISO 8601 in UTC, with milliseconds and a Z, and their names end in Utc:
"checkedInUtc": "2026-11-12T07:58:12.000Z"Wall times are what a person at the venue reads on the agenda. Sessions, shifts, discount codes and sales windows carry them beside the moment, in the venue's own time, without a zone, and their names end in Local:
{
"title": "Opening keynote: software that finds its way",
"startsUtc": "2026-11-12T08:30:00.000Z",
"startsLocal": "2026-11-12T09:30",
"timeZone": "Europe/Amsterdam"
}The event says its venue's IANA time zone in timeZone. Its startDate and endDate are plain dates at the venue.
Which to use
- To compare, sort, store or compute: the moment, in UTC.
- To show a time to somebody: the wall time as it is, or the moment converted to the event's
timeZone. Never to your server's zone: a session at 09:30 in Amsterdam is at 09:30 for everybody who goes, wherever their laptop is. - Clock changes are already in it: a session on the last Sunday of October has the right UTC moment for its wall time.
Sending times
Moments you send (salesEndUtc, endsUtc) are read as UTC whatever they say: an offset such as +01:00 is honoured, a time without one is UTC, never the server's zone. updatedSince is the same.
A new session can be given in wall time (startsLocal, endsLocal) and AttendBeacon converts it with the event's time zone, or in UTC (startsUtc, endsUtc). Wall time is usually what you have: it is what the speaker agreed to.
curl -X POST "https://attendbeacon.com/api/v1/events/b3ac0000-0000-4000-8000-000000000001/sessions" \
-H "Authorization: Bearer $ATTENDBEACON_KEY" \
-H "Content-Type: application/json" \
-d '{ "title": "Closing keynote: what we learned", "kind": "keynote", "startsLocal": "2026-11-13T16:30", "endsLocal": "2026-11-13T17:15" }'await fetch(`${base}/events/${eventId}/sessions`, {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
body: JSON.stringify({ title: "Closing keynote: what we learned", kind: "keynote", startsLocal: "2026-11-13T16:30", endsLocal: "2026-11-13T17:15" })
});Days in summaries
Where the API counts per day (the sales pace), the days are the venue's days in its time zone, so a registration at 00:30 in Amsterdam counts on that day, not the day before in UTC.