Skip to main content

Book Clubs API

Endpoints for managing book clubs and club memberships.

List Clubs

Get a list of all book clubs.

GET /clubs

Authentication

Optional (Bearer token)

Query Parameters

  • scope (optional) - Filter by scope: all, store, user (default: all)
  • storeId (optional) - Filter by store ID (when scope is store)
  • isPublic (optional) - Filter by visibility: true or false
  • limit (optional) - Number of results (default: 20)
  • offset (optional) - Pagination offset (default: 0)

Response

{
"clubs": [
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Science Fiction Book Club",
"description": "Monthly discussions of classic and contemporary sci-fi novels",
"isPublic": true,
"hostId": "550e8400-e29b-41d4-a716-446655440000",
"host": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"displayName": "John Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/johndoe.jpg"
},
"storeId": "660e8400-e29b-41d4-a716-446655440001",
"store": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Downtown Books",
"slug": "downtown-books"
},
"memberCount": 24,
"bookCount": 3,
"createdAt": "2024-01-10T12:00:00Z"
}
],
"total": 1,
"limit": 20,
"offset": 0
}

Errors

  • 500 InternalServerError - Server error

Example

curl "https://api.bookwish.app/clubs?scope=store&storeId=660e8400-e29b-41d4-a716-446655440001"

Create Club

Create a new book club.

POST /clubs

Authentication

Required (Bearer token)

Tier Requirements

  • Free: Cannot create clubs
  • Premium: Can create and host clubs
  • Bookstore: Can create and host clubs

Request Body

{
"name": "Mystery Lovers Book Club",
"description": "We meet monthly to discuss mystery and thriller novels",
"isPublic": true,
"storeId": "660e8400-e29b-41d4-a716-446655440001"
}

Response

{
"id": "770e8400-e29b-41d4-a716-446655440003",
"name": "Mystery Lovers Book Club",
"description": "We meet monthly to discuss mystery and thriller novels",
"isPublic": true,
"hostId": "550e8400-e29b-41d4-a716-446655440000",
"host": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"displayName": "John Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/johndoe.jpg"
},
"storeId": "660e8400-e29b-41d4-a716-446655440001",
"memberCount": 1,
"bookCount": 0,
"createdAt": "2024-03-21T18:00:00Z",
"updatedAt": "2024-03-21T18:00:00Z"
}

Errors

  • 400 ValidationError - Invalid request body
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Insufficient tier (requires Premium or Bookstore)
  • 404 NotFound - Store not found (if storeId provided)
  • 500 InternalServerError - Server error

Example

curl -X POST "https://api.bookwish.app/clubs" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Mystery Lovers Book Club",
"description": "We meet monthly to discuss mystery and thriller novels",
"isPublic": true,
"storeId": "660e8400-e29b-41d4-a716-446655440001"
}'

Get Club

Get detailed information about a specific club.

GET /clubs/:id

Authentication

Optional (Bearer token - required for private clubs)

Path Parameters

  • id - Club ID

Response

{
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Science Fiction Book Club",
"description": "Monthly discussions of classic and contemporary sci-fi novels. We meet on the first Thursday of each month at 7 PM.",
"isPublic": true,
"hostId": "550e8400-e29b-41d4-a716-446655440000",
"host": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"displayName": "John Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/johndoe.jpg",
"tier": "premium"
},
"storeId": "660e8400-e29b-41d4-a716-446655440001",
"store": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Downtown Books",
"slug": "downtown-books",
"logoUrl": "https://cdn.bookwish.app/stores/downtown-books-logo.jpg"
},
"memberCount": 24,
"bookCount": 3,
"books": [
{
"id": "club-book-001",
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"book": {
"id": "bb0e8400-e29b-41d4-a716-446655440006",
"isbn": "9780316769174",
"title": "Dune",
"authors": ["Frank Herbert"],
"coverUrl": "https://covers.bookwish.app/dune.jpg"
},
"status": "current",
"startDate": "2024-03-01",
"endDate": "2024-03-31",
"notes": "Classic sci-fi masterpiece",
"addedAt": "2024-02-15T10:00:00Z"
}
],
"isMember": true,
"memberRole": "member",
"createdAt": "2024-01-10T12:00:00Z",
"updatedAt": "2024-03-15T14:30:00Z"
}

Errors

  • 401 Unauthorized - Private club requires authentication
  • 403 Forbidden - Cannot access private club (not a member)
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Example

curl "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002"

Get My Joined Clubs

Get clubs the authenticated user has joined.

GET /clubs/me/joined

Authentication

Required (Bearer token)

Response

{
"clubs": [
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Science Fiction Book Club",
"description": "Monthly sci-fi discussions",
"isPublic": true,
"memberCount": 24,
"memberRole": "member",
"createdAt": "2024-01-10T12:00:00Z"
}
]
}

Errors

  • 401 Unauthorized - Not authenticated
  • 500 InternalServerError - Server error

Update Club

Update club details.

PUT /clubs/:id

Authentication

Required (Bearer token - host only)

Path Parameters

  • id - Club ID

Request Body

{
"name": "Sci-Fi & Fantasy Book Club",
"description": "Expanded to include fantasy novels! We meet on the first Thursday of each month at 7 PM.",
"isPublic": true
}

Response

{
"id": "770e8400-e29b-41d4-a716-446655440002",
"name": "Sci-Fi & Fantasy Book Club",
"description": "Expanded to include fantasy novels! We meet on the first Thursday of each month at 7 PM.",
"isPublic": true,
"hostId": "550e8400-e29b-41d4-a716-446655440000",
"memberCount": 24,
"updatedAt": "2024-03-21T19:00:00Z"
}

Errors

  • 400 ValidationError - Invalid request body
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not the club host
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Example

curl -X PUT "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Sci-Fi & Fantasy Book Club",
"description": "Expanded to include fantasy novels!"
}'

Delete Club

Delete a book club.

DELETE /clubs/:id

Authentication

Required (Bearer token - host only)

Path Parameters

  • id - Club ID

Response

{
"success": true,
"message": "Club deleted successfully"
}

Errors

  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not the club host
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Example

curl -X DELETE "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002" \
-H "Authorization: Bearer YOUR_TOKEN"

Add Book to Club

Add a book to the club's reading list.

POST /clubs/:id/books

Authentication

Required (Bearer token - host or moderator only)

Path Parameters

  • id - Club ID

Request Body

{
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"status": "upcoming",
"startDate": "2024-04-01",
"endDate": "2024-04-30",
"notes": "Perfect for spring reading"
}

Book Status Values

  • upcoming - Scheduled for future reading
  • current - Currently reading
  • completed - Finished reading

Response

{
"id": "club-book-002",
"clubId": "770e8400-e29b-41d4-a716-446655440002",
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"book": {
"id": "bb0e8400-e29b-41d4-a716-446655440006",
"isbn": "9780316769174",
"title": "The Left Hand of Darkness",
"authors": ["Ursula K. Le Guin"],
"coverUrl": "https://covers.bookwish.app/lefthand.jpg"
},
"status": "upcoming",
"startDate": "2024-04-01",
"endDate": "2024-04-30",
"notes": "Perfect for spring reading",
"addedAt": "2024-03-21T19:30:00Z"
}

Errors

  • 400 ValidationError - Invalid request body
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not host or moderator
  • 404 NotFound - Club or book not found
  • 500 InternalServerError - Server error

Example

curl -X POST "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002/books" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"status": "upcoming",
"startDate": "2024-04-01",
"endDate": "2024-04-30"
}'

Update Club Book

Update a club book's details.

PUT /clubs/:id/books/:bookId

Authentication

Required (Bearer token - host or moderator only)

Path Parameters

  • id - Club ID
  • bookId - Club book ID

Request Body

{
"status": "current",
"notes": "Now reading! Join the discussion."
}

Response

{
"id": "club-book-002",
"clubId": "770e8400-e29b-41d4-a716-446655440002",
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"status": "current",
"startDate": "2024-04-01",
"endDate": "2024-04-30",
"notes": "Now reading! Join the discussion.",
"updatedAt": "2024-04-01T10:00:00Z"
}

Errors

  • 400 ValidationError - Invalid request body
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not host or moderator
  • 404 NotFound - Club or book not found
  • 500 InternalServerError - Server error

Remove Book from Club

Remove a book from the club's reading list.

DELETE /clubs/:id/books/:bookId

Authentication

Required (Bearer token - host or moderator only)

Path Parameters

  • id - Club ID
  • bookId - Club book ID

Response

{
"success": true,
"message": "Book removed from club"
}

Errors

  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not host or moderator
  • 404 NotFound - Club or book not found
  • 500 InternalServerError - Server error

Join Club

Join a book club.

POST /clubs/:id/join

Authentication

Required (Bearer token)

Path Parameters

  • id - Club ID

Response

{
"success": true,
"membership": {
"clubId": "770e8400-e29b-41d4-a716-446655440002",
"userId": "550e8400-e29b-41d4-a716-446655440001",
"role": "member",
"joinedAt": "2024-03-21T20:00:00Z"
}
}

Errors

  • 400 ValidationError - Already a member
  • 401 Unauthorized - Not authenticated
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Example

curl -X POST "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002/join" \
-H "Authorization: Bearer YOUR_TOKEN"

Leave Club

Leave a book club.

DELETE /clubs/:id/leave

Authentication

Required (Bearer token)

Path Parameters

  • id - Club ID

Response

{
"success": true,
"message": "Left club successfully"
}

Errors

  • 400 ValidationError - Not a member or cannot leave (host cannot leave their own club)
  • 401 Unauthorized - Not authenticated
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Example

curl -X DELETE "https://api.bookwish.app/clubs/770e8400-e29b-41d4-a716-446655440002/leave" \
-H "Authorization: Bearer YOUR_TOKEN"

Get Club Members

Get all members of a club.

GET /clubs/:id/members

Authentication

Optional (Bearer token - required for private clubs)

Path Parameters

  • id - Club ID

Response

{
"members": [
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"displayName": "John Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/johndoe.jpg",
"tier": "premium"
},
"role": "host",
"joinedAt": "2024-01-10T12:00:00Z"
},
{
"userId": "550e8400-e29b-41d4-a716-446655440001",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"username": "janedoe",
"displayName": "Jane Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/janedoe.jpg",
"tier": "free"
},
"role": "member",
"joinedAt": "2024-02-05T15:30:00Z"
}
],
"total": 2
}

Member Roles

  • host - Club creator and primary admin
  • moderator - Can manage books and moderate discussions
  • member - Regular member

Errors

  • 401 Unauthorized - Private club requires authentication
  • 403 Forbidden - Cannot access private club (not a member)
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error

Update Member Role

Update a member's role (host only).

PUT /clubs/:id/members/:memberId/role

Authentication

Required (Bearer token - host only)

Path Parameters

  • id - Club ID
  • memberId - User ID of member

Request Body

{
"role": "moderator"
}

Response

{
"success": true,
"membership": {
"userId": "550e8400-e29b-41d4-a716-446655440001",
"role": "moderator",
"updatedAt": "2024-03-21T21:00:00Z"
}
}

Errors

  • 400 ValidationError - Invalid role
  • 401 Unauthorized - Not authenticated
  • 403 Forbidden - Not the club host
  • 404 NotFound - Club or member not found
  • 500 InternalServerError - Server error

Get Club Discussion

Get discussion lines for a club.

GET /clubs/:id/lines

Authentication

Optional (Bearer token - required for private clubs)

Path Parameters

  • id - Club ID

Query Parameters

  • cursor (optional) - Pagination cursor
  • limit (optional) - Number of items (1-100, default: 20)

Response

{
"items": [
{
"id": "aa0e8400-e29b-41d4-a716-446655440010",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"username": "johndoe",
"displayName": "John Doe",
"avatarUrl": "https://cdn.bookwish.app/avatars/johndoe.jpg"
},
"bookId": "bb0e8400-e29b-41d4-a716-446655440006",
"content": "Great discussion today about the themes of identity!",
"clubId": "770e8400-e29b-41d4-a716-446655440002",
"likeCount": 12,
"replyCount": 5,
"createdAt": "2024-03-21T18:00:00Z"
}
],
"nextCursor": "aa0e8400-e29b-41d4-a716-446655440011"
}

Errors

  • 401 Unauthorized - Private club requires authentication
  • 403 Forbidden - Cannot access private club (not a member)
  • 404 NotFound - Club not found
  • 500 InternalServerError - Server error