Live & Sessions
Livestreaming, and the booking flow for 1-on-1 sessions. All endpoints require authentication.
Livestreams
| Method | Path | Purpose |
|---|---|---|
GET | /livestreams/credentials | Get (or lazily create) your Mux stream credentials |
POST | /livestreams/credentials/regenerate | Rotate the stream key |
POST | /livestreams | Create a livestream record |
POST | /livestreams/:id/enable | Enable the Mux live stream |
POST | /livestreams/:id/end | End it |
GET | /livestreams/:id | Fetch a livestream (with playback id) |
GET | /livestreams/:id/messages | Chat history |
POST | /livestreams/:id/messages | Send a chat message |
Credentials exist from registration
registerUser creates a LiveStream record with Mux credentials, so GET /livestreams/credentials normally returns an existing record rather than provisioning one.
{
"id": "clx…",
"streamKey": "…",
"muxPlaybackId": "…",
"muxLivestreamId": "…",
"status": "idle"
}The creator publishes RTMP to Mux with streamKey; viewers play HLS using muxPlaybackId.
streamKey is a credential
Anyone holding it can broadcast as that creator. Never log it, never include it in a response meant for anyone but the owner, and rotate it with /livestreams/credentials/regenerate if it leaks.
Status is webhook-driven
LiveStream.status and User.isLive are set by Mux webhooks (video.live_stream.active / .idle), not by the client. Do not set them from the app. See Livestreaming.
Chat
Livestream chat is persisted as LiveStreamMessage rows, so late joiners see history. Coin gifting during a stream produces the CREATOR_REDEEM ledger entries that feed creator payouts.
Sessions (e-dates)
| Method | Path | Purpose |
|---|---|---|
POST | /sessions | Book a session |
GET | /sessions/mine | Your sessions |
GET | /sessions/:id | One session |
PATCH | /sessions/:id/cancel | Cancel |
POST /sessions
{
playpalId: string, // the creator being booked
startDate: string, // ISO 8601 datetime
endDate: string, // ISO 8601 datetime
duration: number, // positive integer
notes?: string, // max 2000 chars
}Returns 201 with the created session. The purchaser is the authenticated user. A privateChannelRoom is associated with the session, and only the two parties can obtain a LiveKit token for it.
GET /sessions/mine
| Parameter | Values | Meaning |
|---|---|---|
role | playpal | purchaser | Which side of the booking |
status | upcoming | past | Time filter |
cursor | opaque | Pagination |
limit | number | Page size |
Note that status here is a time filter, distinct from Session.status (scheduled / active / completed / cancelled).
Cancellation
PATCH /sessions/:id/cancel sets status to cancelled and stamps cancelledAt, and fires a SESSION_CANCELLED notification. Refund handling is not implemented — the payment was collected by RevenueCat and there is no compensating flow. Planned
Availability
Creators publish when they can be booked.
Working hours
| Method | Path | Purpose |
|---|---|---|
GET | /availability | Your working hours, formatted |
GET | /availability/raw | Raw rows |
PUT | /availability | Replace the whole schedule |
PATCH | /availability/day | Update one day |
Blocked dates
| Method | Path | Purpose |
|---|---|---|
GET | /availability/blocked-dates | List blocked dates |
POST | /availability/block-date | Block a specific date |
DELETE | /availability/block-date | Unblock |
Recurring hours and one-off blocked dates share the Availability model — recurring rows use dayOfWeek + startTime + endTime, blocked rows use date + blocked: true.
Checking availability
| Method | Path | Purpose |
|---|---|---|
GET | /availability/check | Is you free at a time? |
GET | /users/:userId/availability | Another user's public availability |
GET | /users/:userId/availability/check | Is they free at a time? |
The booking flow calls /users/:userId/availability to render the calendar, then /users/:userId/availability/check before submitting.
No timezone handling
startTime and endTime are stored as strings ("09:00") with no timezone column. A creator in Los Angeles and a fan in Berlin will disagree about when "09:00" is. Fix this before sessions cross regions — it needs a timezone on User and conversion at both read and write.
Related
- Livestreaming & Voice
- Messaging & Channels — room tokens and access rules
- Monetization — how session revenue reaches creators
