Chat Messages & Mobile Endpoints
These endpoints power the Staty mobile app. They authenticate with a user
session token (Authorization: Bearer <utoken>), not an API key — the token
is issued by POST /api/v1/users/loginUser and is signature-verified with
expiry enforced.
Chat messages
Team chat is scoped to a DivisionTeam (the same entity games and rosters
resolve to). A user can read and post in a team’s chat when they have a linked
Player on that team, or when their account email matches an admin of the
team’s division, contest, or tournament. Messages with kind: "announcement"
can only be posted by those admins.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/v1/chatMessages/team/:divisionTeamId?limit=50&before=<id> | User token | Newest-first history; pass the oldest loaded _id as before to page |
| POST | /api/v1/chatMessages | User token | Send { divisionTeam, text, kind? } (text ≤ 2000 chars) |
Realtime (Socket.IO)
The API also serves a Socket.IO endpoint on the same origin. Authenticate the
handshake with the user token (auth: { token }), then:
join:team(divisionTeamId) — join a team room (membership-checked)message:send({ divisionTeam, text, kind? }, ack) — send a messagemessage:new— broadcast to the room for every new messageleave:team(divisionTeamId) — leave the room
Messages sent over REST and over the socket are equivalent — both persist, broadcast to the room, and trigger push notifications.
My teams & games
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/v1/users/me/teams | User token | The user’s DivisionTeams (via their linked Players), deduped; archived and test teams excluded. ?include= roots: team, division, league, organization, players |
| GET | /api/v1/users/me/games?from=<ISO date>&limit=50 | User token | Upcoming games across all the user’s teams, date-ascending; cancelled games included (flagged), hidden/bye games excluded |
Players link to user accounts automatically at signup by email, or explicitly
via POST /api/v1/players/link-user (authenticated; the player must have been
registered with the caller’s email).
Team events
Manager/admin-created non-game activities (practice, scrimmage, social) that
appear in the mobile schedule alongside games. A manager is the team’s
registrant or an email match against the registration’s team managers; org
admins always qualify. Events follow the games date contract (date instant +
globalDate display date + time string); the client sends a dateKey
(“YYYY-MM-DD” in the device’s calendar) and the server derives globalDate.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/v1/users/me/events?from&limit | User token | Events across all the user’s teams |
| GET | /api/v1/teamEvents/team/:divisionTeamId?from= | User token | A team’s events (members) |
| GET | /api/v1/teamEvents/:id | User token | Event detail (members) |
| POST | /api/v1/teamEvents | User token | Create (managers/admins) — { divisionTeam, title, eventType?, date, dateKey?, time?, durationMinutes?, location?, notes? } |
| PUT | /api/v1/teamEvents/:id | User token | Edit / set isCancelled (managers/admins) |
| DELETE | /api/v1/teamEvents/:id | User token | Delete (managers/admins) |
GET /api/v1/users/me/teams/:divisionTeamId/access returns the caller’s
{ isMember, isAdmin, isManager } flags for a team.
Availability (RSVP)
Per-Player answers (a parent answers for each linked player) on a game or a team event. Upsert-only — re-answering overwrites; there is no delete. Writes are owner-only (the player’s linked account); reads are team-scoped so a team only sees its own answers.
| Method | Path | Auth | Description |
|---|---|---|---|
| PUT | /api/v1/availabilities | User token | Upsert { game | teamEvent, player, status: "yes"|"no"|"maybe", note? } (exactly one of game/teamEvent) |
| GET | /api/v1/availabilities/game/:gameId?team=<divisionTeamId> | User token | A team’s answers for a game (members) |
| GET | /api/v1/availabilities/teamEvent/:id | User token | Answers for an event (members) |
Assignments
Per-game/per-event duties (snacks, carpool, scorekeeper) assigned to a roster
player. Managers/admins create, reassign, and delete; the assignee’s linked
account can toggle completed. The assignee receives a push notification.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/assignments | User token | Create { game | teamEvent, player, title, note? } (managers/admins) |
| GET | /api/v1/assignments/game/:gameId?team=<divisionTeamId> | User token | A team’s duties for a game (members) |
| GET | /api/v1/assignments/teamEvent/:id | User token | Duties for an event (members) |
| PUT | /api/v1/assignments/:id | User token | Edit / reassign (managers/admins) |
| PUT | /api/v1/assignments/:id/completed | User token | Toggle done (managers/admins or the assignee’s owner) |
| DELETE | /api/v1/assignments/:id | User token | Delete (managers/admins) |
Team photos
A team-scoped gallery. Members upload (multipart field upload, ≤10MB — the
mobile app resizes to ≤2048px first); the uploader or an admin can delete.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/teamPhotos/team/:divisionTeamId | User token | Multipart upload (members); optional caption, width, height fields |
| GET | /api/v1/teamPhotos/team/:divisionTeamId?before=&limit= | User token | Newest-first pages (members) |
| DELETE | /api/v1/teamPhotos/:id | User token | Uploader or admin |
Push tokens
The mobile app registers its Expo push token after sign-in; the API notifies team members about new chat messages, new team events, assignments, and game/event-day reminders (reminder taps deep-link to the game or event detail screen).
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/pushTokens | User token | Upsert { token, platform?, deviceId? } — a token re-registered by another account is re-owned |
| DELETE | /api/v1/pushTokens | User token | Remove { token } (sign-out); stale tokens are also pruned automatically |