Skip to main content
The events module covers the full events surface: creating and editing events, the RSVP lifecycle, host and invite management, and the guest list. It maps directly to the Events API. Because the Node SDK authenticates with a service key (it acts as the whole project, not a single end user), most write functions take an explicit userId naming the user the action is performed as. For host- and invite-management functions, userId is instead the target user (the host/invitee), and the action is authorized as the project.
Image upload caveat. The Node SDK does not support inline cover/gallery upload on createEvent/updateEvent yet. Create the event first, then attach images with sublay.storage.uploadImage using its eventId parameter. (The browser JS SDK and the React SDK do support inline upload.)
Requires the events bundle. Space-scoping needs the spaces bundle; images need files-images; notifications need notifications.

createEvent

Creates an event. The userId you pass becomes the creator and is auto-added to hostIds. Returns the event with inline rsvpCounts.
const event = await sublay.events.createEvent({
  userId: "usr_abc123",
  title: "Launch Party",
  type: "physical",
  startTime: "2026-09-01T18:00:00.000Z",
  endTime: "2026-09-01T22:00:00.000Z",
  timezone: "America/New_York",
  venueName: "The Loft",
  address: "123 Main St, New York, NY",
  location: { latitude: 40.7128, longitude: -74.006 },
  capacity: 100,
  visibility: "public",
});
title
string
required
Event title. 1–300 characters.
startTime
string
required
ISO datetime when the event starts.
type
"online" | "physical" | "hybrid"
required
Event format. online requires url; physical requires address or location; hybrid requires both.
userId
string
The user to create the event as (creator + first host). With a service key this may be any user.
description
string
Optional description.
endTime
string
Optional ISO end datetime.
timezone
string
Optional IANA timezone.
url
string
Join/stream URL.
venueName
string
Venue name.
address
string
Street address.
location
{ latitude: number; longitude: number }
Coordinates for proximity search.
spaceId
string
Scope the event to a space. Required when visibility is "members".
visibility
"public" | "members" | "invite"
Defaults to "public".
capacity
number
Max going RSVPs. Omit for unlimited.
allowMaybe
boolean
Allow "maybe" RSVPs. Defaults to true.
guestListVisible
boolean
Expose the named guest list to non-hosts. Defaults to true.
hostIds
string[]
Additional host user IDs (the creator is always added).
metadata
object
Arbitrary key-value data. Up to 1 MB.
ReturnsPromise<Event>

fetchEvent

Fetches a single event by ID. Pass userId to resolve visibility for that user and to populate userRsvp (with the userRsvp include).
const event = await sublay.events.fetchEvent({
  eventId: "evt_abc123",
  include: "user,space,files,userRsvp",
  userId: "usr_abc123",
});
eventId
string
required
The event ID.
include
string
Comma-separated associations: "user", "space", "files", "userRsvp".
userId
string
The requester id, for visibility resolution and userRsvp enrichment.
ReturnsPromise<Event>

fetchManyEvents

Lists events with visibility enforced, plus filtering, sorting, geo, and free-text search. Pass userId to resolve member/invite/host visibility and to use the myRsvp filter.
const { data, pagination } = await sublay.events.fetchManyEvents({
  timeWindow: "upcoming",
  sortBy: "startTime",
  sortDir: "asc",
  type: "physical",
  page: 1,
  limit: 20,
  userId: "usr_abc123",
  include: "user,userRsvp",
});
page
number
Page number (1-indexed). Defaults to 1.
limit
number
Results per page. Capped at 100.
sortBy
"startTime" | "going"
Sort field. Defaults to "startTime".
sortDir
"asc" | "desc"
Sort direction. Defaults to "asc".
timeWindow
"upcoming" | "ongoing" | "past"
Derived time window.
startsAfter
string
ISO datetime lower bound on startTime.
startsBefore
string
ISO datetime upper bound on startTime.
spaceId
string
Restrict to one space.
hostId
string
Only events this user hosts.
type
"online" | "physical" | "hybrid"
Filter by type.
status
"active" | "cancelled"
Defaults to "active".
myRsvp
string
Comma-separated statuses the requester RSVP’d with, e.g. "going,maybe". Requires userId.
locationFilters
{ latitude: string; longitude: string; radius: string }
Proximity filter (radius in meters).
titleFilters
{ hasTitle?; includes?; doesNotInclude? }
Free-text filter on title.
descriptionFilters
{ hasDescription?; includes?; doesNotInclude? }
Free-text filter on description.
include
string
Comma-separated associations.
userId
string
The requester id (visibility + myRsvp + userRsvp).
ReturnsPromise<PaginatedResponse<Event>>

updateEvent

Edits an event’s mutable fields. Host-only at the API level; with a service key the call is authorized as the project. hostIds, status, and spaceId are not editable here.
const event = await sublay.events.updateEvent({
  eventId: "evt_abc123",
  capacity: 150,
  description: "Now with more space!",
});
eventId
string
required
The event ID.
title
string
New title.
description
string
New description.
startTime
string
New ISO start datetime.
endTime
string
New ISO end datetime.
timezone
string
New timezone.
type
"online" | "physical" | "hybrid"
New type (re-validates location fields).
url
string
New URL.
venueName
string
New venue name.
address
string
New address.
location
{ latitude: number; longitude: number }
New coordinates.
visibility
"public" | "members" | "invite"
New visibility.
capacity
number
New capacity.
allowMaybe
boolean
Allow "maybe" RSVPs.
guestListVisible
boolean
Expose the guest list.
metadata
object
New metadata.
ReturnsPromise<Event>

cancelEvent

Cancels an event (sets status: "cancelled"). The event stays fetchable but rejects new RSVPs.
const event = await sublay.events.cancelEvent({ eventId: "evt_abc123" });
eventId
string
required
The event ID.
ReturnsPromise<Event>

deleteEvent

Permanently (or soft-, per the project’s eventDeletion settings) deletes an event and cleans up its RSVPs and invites.
await sublay.events.deleteEvent({ eventId: "evt_abc123" });
eventId
string
required
The event ID.
ReturnsPromise<void>

setRsvp

Sets or changes a user’s RSVP. Transitions into going are capacity-checked.
const event = await sublay.events.setRsvp({
  eventId: "evt_abc123",
  status: "going",
  userId: "usr_abc123",
});
eventId
string
required
The event ID.
status
"going" | "maybe" | "not_going"
required
The RSVP response.
userId
string
The user to RSVP as. With a service key this may be any user.
ReturnsPromise<Event> (with refreshed rsvpCounts)

withdrawRsvp

Removes a user’s RSVP. Idempotent.
const event = await sublay.events.withdrawRsvp({
  eventId: "evt_abc123",
  userId: "usr_abc123",
});
eventId
string
required
The event ID.
userId
string
The user to withdraw. With a service key this may be any user.
ReturnsPromise<Event>

addHost

Grants a user host privileges. The userId is the target host; the action is authorized as the project.
const event = await sublay.events.addHost({
  eventId: "evt_abc123",
  userId: "usr_cohost",
});
eventId
string
required
The event ID.
userId
string
required
The user to grant host on the event.
ReturnsPromise<Event>

removeHost

Revokes a user’s host privileges. Rejected if it would leave the event with no hosts.
const event = await sublay.events.removeHost({
  eventId: "evt_abc123",
  userId: "usr_cohost",
});
eventId
string
required
The event ID.
userId
string
required
The host to remove.
ReturnsPromise<Event>

addInvite

Invites a user to the event. Idempotent. The userId is the target invitee.
const event = await sublay.events.addInvite({
  eventId: "evt_abc123",
  userId: "usr_guest",
});
eventId
string
required
The event ID.
userId
string
required
The user to invite (userId only — never a foreign ID).
ReturnsPromise<Event>

removeInvite

Removes a user’s invite, revoking their access and dropping their RSVP.
const event = await sublay.events.removeInvite({
  eventId: "evt_abc123",
  userId: "usr_guest",
});
eventId
string
required
The event ID.
userId
string
required
The invitee to remove.
ReturnsPromise<Event>

fetchInvitees

Host-only invitee (guest) list. Returns paginated EventInvite records with the invited user populated.
const { data, pagination } = await sublay.events.fetchInvitees({
  eventId: "evt_abc123",
  page: 1,
  limit: 20,
});
eventId
string
required
The event ID.
page
number
Page number (1-indexed).
limit
number
Results per page. Capped at 100.
ReturnsPromise<PaginatedResponse<EventInvite>>

fetchEventRsvps

Named RSVP (guest) list. Returns paginated EventRsvp records with the user populated. Visible to hosts always, to any viewer when guestListVisible is true, or to service keys. RSVP counts themselves are public via the event’s rsvpCounts.
const { data, pagination } = await sublay.events.fetchEventRsvps({
  eventId: "evt_abc123",
  status: "going,maybe",
  page: 1,
  limit: 20,
});
eventId
string
required
The event ID.
status
string
Comma-separated statuses to filter by, e.g. "going,maybe". Omit for all.
page
number
Page number (1-indexed).
limit
number
Results per page. Capped at 100.
ReturnsPromise<PaginatedResponse<EventRsvp>>

Attaching images

Create the event, then upload a cover or gallery image and associate it with eventId:
import { readFile } from "node:fs/promises";

const event = await sublay.events.createEvent({
  userId: "usr_abc123",
  title: "Launch Party",
  type: "online",
  url: "https://meet.example.com/launch",
  startTime: "2026-09-01T18:00:00.000Z",
});

const buffer = await readFile("./cover.jpg");
await sublay.storage.uploadImage({
  file: new Uint8Array(buffer),
  filename: "cover.jpg",
  mimeType: "image/jpeg",
  imageOptions: { mode: "original-aspect", sizes: { full: 1600 }, format: "webp" },
  eventId: event.id,
  userId: "usr_abc123",
});
Uploading via storage.uploadImage attaches a gallery image (a File with the event’s eventId). Setting it as the event’s single cover (coverImageId) is done by the inline-upload path, which the Node SDK does not yet expose.