Skip to content

API Endpoints

All endpoints are prefixed with /api/v1. All endpoints require a valid Clerk JWT in the Authorization: Bearer <token> header.

Successful responses return the resource directly:

{
"id": "user_123",
"displayName": "Carmen"
}

Paginated responses return a list plus pagination metadata:

{
"items": [{ "id": "evt_123", "title": "Hack Night" }],
"meta": { "total": 100, "limit": 20, "offset": 0 }
}

Error responses use RFC 7807 Problem Details with the appropriate HTTP status code:

{
"type": "https://social-osu.app/problems/not-found",
"title": "Resource not found",
"status": 404,
"detail": "Event evt_123 was not found"
}

All paginated endpoints use limit (default 20, max 100) and offset (default 0). All timestamps are UTC (ISO 8601).

MethodPathDescription
GET/api/v1/users/meGet authenticated user’s profile
PATCH/api/v1/users/meUpdate profile fields
GET/api/v1/users/:idGet public profile of a user
POST/api/v1/users/:id/followFollow a user
DELETE/api/v1/users/:id/followUnfollow a user
GET/api/v1/users/:id/followersList a user’s followers. Params: limit, offset
GET/api/v1/users/:id/followingList users that a user follows. Params: limit, offset
MethodPathDescription
GET/api/v1/social/feedGet events from followed users. Params: limit, offset
MethodPathDescription
GET/api/v1/eventsList events. Filters: type, category, startDate, endDate, source, status, search, limit, offset
POST/api/v1/eventsCreate an event or gig
GET/api/v1/events/:idGet single event with full detail
PATCH/api/v1/events/:idUpdate event (owner only; forbidden for external events)
DELETE/api/v1/events/:idDelete event (owner only; forbidden for external events)

:gigId is an Event ID. The system validates that the event has type = GIG. Returns 400 if the event is not a gig.

MethodPathDescription
POST/api/v1/gigs/:gigId/applicationsApply to a gig. Body: { message? }
GET/api/v1/gigs/:gigId/applicationsList applications (owner sees all; applicant sees own). Params: limit, offset
PATCH/api/v1/gigs/:gigId/applications/:appIdUpdate application status (gig owner only). Body: { status }
MethodPathDescription
GET/api/v1/collectionsList authenticated user’s collections
POST/api/v1/collectionsCreate a collection
GET/api/v1/collections/:idGet collection with items (respects visibility)
PATCH/api/v1/collections/:idUpdate collection (owner only)
DELETE/api/v1/collections/:idDelete collection and items (owner only)
GET/api/v1/collections/:id/itemsList events in collection. Params: limit, offset
POST/api/v1/collections/:id/itemsAdd event to collection. Body: { eventId }
DELETE/api/v1/collections/:id/items/:eventIdRemove event from collection
MethodPathDescription
POST/api/v1/interactionsRecord a user interaction
MethodPathDescription
GET/api/v1/recommendationsGet personalized feed. Params: limit, offset, type
MethodPathDescription
GET/api/v1/conversationsList user’s conversations. Params: limit, offset
POST/api/v1/conversationsCreate a new conversation
GET/api/v1/conversations/:id/messagesGet message history. Params: limit, offset
POST/api/v1/conversations/:id/messagesSend message; returns streamed SSE response
MethodPathDescription
GET/api/v1/notificationsList notifications. Params: unread, limit, offset
GET/api/v1/notifications/unread-countGet unread notification count
PATCH/api/v1/notifications/:idUpdate notification (mark as read)
POST/api/v1/notifications/mark-all-readMark all notifications as read
HTTP StatusCodeWhen
400BAD_REQUESTInvalid input, applying to non-gig event, applying to cancelled gig
401UNAUTHORIZEDMissing or invalid JWT
403FORBIDDENOwnership violation, self-application to own gig
404NOT_FOUNDResource not found or private resource accessed by non-owner
409CONFLICTDuplicate application, duplicate collection item, duplicate follow
500INTERNAL_ERRORUnexpected server error