Skip to main content

POST /api/v1/reservations

Create a new meeting room reservation. The system validates time slots, checks for conflicts, enforces business rules, and syncs with Google Calendar.

Authentication

Required: JWT token via Authorization: Bearer <token> header

Rate Limiting

  • Rate: 30 requests per 2 seconds per IP
  • Status Code on Limit: 429 Too Many Requests

Request Body

roomId
integer
required
The ID of the room to reserve. Must be greater than 0.
startTime
string
required
ISO 8601 timestamp in UTC format. Must be:
  • In the future
  • Within school hours (6:00 AM - 8:00 PM)
  • In UTC timezone
Example: 2025-01-28T14:00:00Z
endTime
string
required
ISO 8601 timestamp in UTC format. Must be:
  • After startTime
  • Within school hours (6:00 AM - 8:00 PM)
  • In UTC timezone
  • Maximum duration:
    • Students: 4 hours
    • Staff: Unlimited
Example: 2025-01-28T16:00:00Z

Response

201 Created
Id
integer
required
The unique identifier for the created reservation
roomId
integer
required
The ID of the reserved room
startTime
string
required
ISO 8601 timestamp of reservation start time in UTC
endTime
string
required
ISO 8601 timestamp of reservation end time in UTC
createdBy
object
required
Information about the user who created the reservation

Error Responses

error
string
Error message describing what went wrong
details
object
Additional details for validation errorsContains field-level error messages for invalid input
400 Bad Request - Invalid request body
{
  "error": "Invalid request body"
}
400 Bad Request - Validation errors
{
  "error": "validation failed",
  "details": {
    "roomId": "must be greater than 0",
    "startTime": "must be in the future",
    "endTime": "must be after start time"
  }
}
400 Bad Request - Exceeds maximum duration
{
  "error": "reservation exceeds maximum allowed duration"
}
401 Unauthorized - Missing or invalid JWT token
{
  "error": "unauthorized"
}
404 Not Found - Room does not exist
{
  "error": "room not found"
}
409 Conflict - Time slot already booked
{
  "error": "this time slot is already booked"
}
500 Internal Server Error - Server error
{
  "error": "Internal server error"
}

Examples

curl -X POST http://localhost:8080/api/v1/reservations \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "roomId": 1,
    "startTime": "2025-01-28T14:00:00Z",
    "endTime": "2025-01-28T16:00:00Z"
  }'

Business Rules

  • Future Times Only: Cannot book times in the past
  • School Hours: Bookings must be between 6:00 AM - 8:00 PM
  • Duration Limits:
    • Students: Maximum 4 hours per reservation
    • Staff: No duration limit
  • Conflict Prevention: System prevents overlapping reservations
  • Email Notification: Confirmation email sent automatically
  • Calendar Sync: Reservation added to Google Calendar
Source: internal/handler/handler_reservations.go:18

GET /api/v1/reservations

Retrieve unavailable time slots for all rooms within a specified date range. Shows which time slots are booked, with privacy controls based on user role.

Authentication

Required: JWT token via Authorization: Bearer <token> header

Rate Limiting

  • Rate: 30 requests per 2 seconds per IP
  • Status Code on Limit: 429 Too Many Requests

Query Parameters

start
string
required
Start date in YYYY-MM-DD formatExample: 2025-01-28
end
string
required
End date in YYYY-MM-DD formatMaximum range: 60 days from start dateExample: 2025-02-01

Response

200 OK - Array of rooms with their reserved slots
roomId
integer
required
The unique identifier of the room
roomName
string
required
The name of the room
slots
array
required
Array of reserved time slots for this room

Error Responses

error
string
Error message describing what went wrong
details
object
Additional details for validation errors
400 Bad Request - Invalid date format or range
{
  "error": "validation failed",
  "details": {
    "start": "invalid date format, expected YYYY-MM-DD",
    "end": "date range cannot exceed 60 days"
  }
}
401 Unauthorized - Missing or invalid JWT token
{
  "error": "unauthorized"
}
500 Internal Server Error - Server error
{
  "error": "Internal server error"
}

Examples

curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  "http://localhost:8080/api/v1/reservations?start=2025-01-28&end=2025-02-01"

Privacy Rules

Booking details (bookedBy field) are visible to:
  • The person who made the booking
  • Staff members
Other users see time slots marked as booked with bookedBy: null. Source: internal/handler/handler_reservations.go:73

DELETE /api/v1/reservations/

Cancel an existing reservation. Authorization rules apply based on user role.

Authentication

Required: JWT token via Authorization: Bearer <token> header

Rate Limiting

  • Rate: 30 requests per 2 seconds per IP
  • Status Code on Limit: 429 Too Many Requests

Path Parameters

id
integer
required
The unique identifier of the reservation to cancel

Response

204 No Content - Reservation successfully cancelled (no response body)

Error Responses

error
string
Error message describing what went wrong
400 Bad Request - Invalid reservation ID
{
  "error": "validation failed",
  "details": {
    "id": "must be a valid integer"
  }
}
401 Unauthorized - Missing or invalid JWT token
{
  "error": "unauthorized"
}
403 Forbidden - Not authorized to cancel this reservation
{
  "error": "unauthorized to cancel this reservation"
}
404 Not Found - Reservation does not exist
{
  "error": "reservation not found"
}
500 Internal Server Error - Server error
{
  "error": "Internal server error"
}

Examples

curl -X DELETE http://localhost:8080/api/v1/reservations/123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Authorization Rules

Users can cancel a reservation if:
  • They created the reservation themselves, OR
  • They have a staff role (staff can cancel any reservation)
Otherwise, a 403 Forbidden error is returned.

Side Effects

  • Email Notification: Cancellation notice sent automatically
  • Calendar Sync: Event removed from Google Calendar
  • Database: Reservation marked as cancelled
Source: internal/handler/handler_reservations.go:110

Build docs developers (and LLMs) love