Slatis Public API v1 is open for beta testers Register on the waitlist →
Slatis

API Conventions

Reference for recurring data formats used across every Slatis endpoint: IANA timezones, ISO 8601 timestamps, and pagination.

Timezones

The Slatis API accepts and returns timezone values using the IANA Time Zone Database format — a globally maintained registry of timezone identifiers maintained by the Internet Assigned Numbers Authority.

Format

IANA timezone strings follow a Region/City pattern:

StringLocation
America/New_YorkUS Eastern Time (auto-adjusts for DST)
America/Los_AngelesUS Pacific Time
America/ChicagoUS Central Time
Europe/MadridSpain
Europe/LondonUnited Kingdom
Asia/TokyoJapan
Asia/KolkataIndia (IST, no DST)
Australia/SydneyAustralia Eastern
Pacific/AucklandNew Zealand
UTCCoordinated Universal Time

IANA identifiers account for Daylight Saving Time automatically. Prefer them over fixed offsets like UTC+2 — fixed offsets do not shift when DST changes.

How to find a timezone string

In the browser:

Intl.DateTimeFormat().resolvedOptions().timeZone
// → "America/New_York"

In Node.js:

Intl.DateTimeFormat().resolvedOptions().timeZone

In Python:

from datetime import datetime, timezone
datetime.now().astimezone().tzinfo.key  # on Python 3.9+
# → "America/New_York"

Full list: The complete database is at data.iana.org/time-zones — most frameworks also ship it as a local package (@vvo/tzdb, tzdata, etc.).

Timezones in the API

  • Availability and free/busy — pass a timezone to filter slots to a member's working hours. Returned slot times are always UTC regardless.
  • Bookings — the attendee's timezone field is stored for display and confirmation email formatting. It does not affect the stored UTC time.
  • Event types — an optional timezone override forces slot generation to use a specific locale rather than each member's calendar timezone.

Date and time format

All date-time values in the Slatis API use ISO 8601 format with UTC offset:

2026-05-01T14:00:00.000Z
│          │            └─ Z = UTC (equivalent to +00:00)
│          └─ Time component (24-hour)
└─ Date component

Producing ISO 8601 strings

JavaScript / TypeScript:

new Date().toISOString()
// → "2026-05-01T14:00:00.000Z"
 
// From a local date + timezone (use a library like date-fns-tz):
import { zonedTimeToUtc } from 'date-fns-tz'
zonedTimeToUtc('2026-05-01 14:00', 'America/New_York').toISOString()

Python:

from datetime import datetime, timezone
datetime.now(timezone.utc).isoformat()
# → "2026-05-01T14:00:00.000000+00:00"

Go:

time.Now().UTC().Format(time.RFC3339)
// → "2026-05-01T14:00:00Z"

Always send times in UTC (Z suffix). Sending a local time without an offset (e.g. 2026-05-01T14:00:00) may be interpreted incorrectly.

Date-only parameters

Some parameters accept a date without a time component, using YYYY-MM-DD format:

2026-05-01

These appear on endpoints where only the calendar date matters, such as GET /v1/team/members/available?date=2026-05-01.


Pagination

The Slatis API uses two pagination styles depending on the endpoint.

Cursor-based pagination

Used by GET /v1/bookings. Each page returns a next_cursor — pass it as the cursor query parameter on the next request.

{
  "success": true,
  "bookings": [...],
  "pagination": {
    "next_cursor": "bkg_01xyz",
    "has_more": true
  }
}
PropTypeDefault
next_cursor
string | null
-
has_more
boolean
-

Iterate all pages using the SDK:

let cursor: string | undefined
const allBookings = []
 
do {
  const result = await slatis.bookings.list({ status: 'SCHEDULED', limit: 100, cursor })
  allBookings.push(...result.bookings)
  cursor = result.pagination.next_cursor ?? undefined
} while (cursor)

Offset-based pagination

Used by team members, webhooks, and delivery history endpoints. Each page returns total, limit, offset, and has_more.

{
  "success": true,
  "members": [...],
  "pagination": {
    "total": 142,
    "limit": 25,
    "offset": 0,
    "has_more": true
  }
}
PropTypeDefault
total
integer
-
limit
integer
-
offset
integer
-
has_more
boolean
-

Iterate all pages using offset:

async function fetchAll<T>(
  fetch: (offset: number) => Promise<{ items: T[]; pagination: { has_more: boolean; limit: number } }>
): Promise<T[]> {
  const results: T[] = []
  let offset = 0
 
  while (true) {
    const { items, pagination } = await fetch(offset)
    results.push(...items)
    if (!pagination.has_more) break
    offset += pagination.limit
  }
 
  return results
}

The SDK's team.getMembers() and team.getAvailableMembers() return the full { members, pagination } envelope directly, so you can use pagination.has_more without unwrapping.

On this page