Mobile Sessions API
The Sessions API enables two devices to share observation state in real time — for example, pairing a phone running the PWA with a laptop controlling a rotor, or letting two observers collaborate on the same tracking session. Each session is identified by a unique token and expires after 24 hours.
Once a session is created and joined, the paired devices communicate over a WebSocket relay at /ws/session/{token} (documented in the Tracking API).
Create Session
Section titled “Create Session”Creates a new pairing session and returns a unique token. The session expires 24 hours after creation.
POST /api/sessionsNo request body is required.
Response (201 Created)
Section titled “Response (201 Created)”{ "token": "a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2", "created_at": "2026-02-14T18:00:00Z", "expires_at": "2026-02-15T18:00:00Z", "is_paired": false}| Field | Type | Description |
|---|---|---|
token | string | URL-safe base64 token (43 characters) for identifying the session |
created_at | datetime | When the session was created |
expires_at | datetime | When the session will expire (24 hours from creation) |
is_paired | boolean | Whether a second device has joined the session |
Get Session
Section titled “Get Session”Retrieves the current state of an existing session.
GET /api/sessions/{token}| Parameter | Type | Description |
|---|---|---|
token | string (path) | The session token |
Response
Section titled “Response”{ "token": "a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2", "created_at": "2026-02-14T18:00:00Z", "expires_at": "2026-02-15T18:00:00Z", "is_paired": true}Returns 404 if the session token does not exist. Returns 410 Gone if the session has expired.
Join Session
Section titled “Join Session”Joins an existing session from a second device. This sets is_paired to true and optionally records the joining device’s information.
POST /api/sessions/{token}/join| Parameter | Type | Description |
|---|---|---|
token | string (path) | The session token to join |
Request Body
Section titled “Request Body”{ "device_info": "iPhone 15 Pro / Safari 19"}| Field | Type | Required | Description |
|---|---|---|---|
device_info | string or null | No | Free-form description of the joining device |
Response
Section titled “Response”{ "token": "a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2", "created_at": "2026-02-14T18:00:00Z", "expires_at": "2026-02-15T18:00:00Z", "is_paired": true}Returns 404 if the session token does not exist. Returns 410 Gone if the session has expired.
Delete Session
Section titled “Delete Session”Ends a session immediately, removing it from the database. Any WebSocket connections on this session token will be closed by the relay.
DELETE /api/sessions/{token}| Parameter | Type | Description |
|---|---|---|
token | string (path) | The session token to delete |
Response
Section titled “Response”Returns 204 No Content on success. Returns 404 if the session token does not exist.
Session Lifecycle
Section titled “Session Lifecycle”A typical pairing flow works as follows:
- Device A calls
POST /api/sessionsand receives a token. - Device A displays the token (or a QR code encoding it) for the second device.
- Device B calls
POST /api/sessions/{token}/joinwith optional device info. - Both devices open a WebSocket connection to
/ws/session/{token}and begin exchanging real-time state (target coordinates, rotor position, tracking mode). - Either device can call
DELETE /api/sessions/{token}to end the session, or it expires automatically after 24 hours.