Skip to content
Shubham Kale edited this page Jun 1, 2026 · 3 revisions

API Documentation β€” Event Management System

Base URL: http://localhost:8081 Auth: Bearer JWT token in Authorization header Format: All dates in ISO 8601 β€” yyyy-MM-ddTHH:mm:ss


Table of Contents

  1. Authentication
  2. Events
  3. Venues
  4. Organizations
  5. User Profile
  6. Categories
  7. Event Registration
  8. Waitlist
  9. Reviews & Ratings
  10. Bookmarks
  11. Notifications
  12. Dashboard & Analytics
  13. Export
  14. Admin
  15. AI Recommendations
  16. System
  17. Error Reference

1. Authentication

POST /api/auth/register

Register a new user account.

Auth: Public

Request:

{
  "name": "Shubham Kale",
  "email": "shubham@example.com",
  "password": "secret123"
}

Response β€” 200 OK:

{
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsInN1YiI6InNodWJoYW1AZXhhbXBsZS5jb20ifQ.abc123",
  "email": "shubham@example.com",
  "name": "Shubham Kale",
  "role": "USER"
}

Error β€” 400 Duplicate Email:

{
  "status": 400,
  "message": "Email already registered: shubham@example.com",
  "timestamp": "2026-05-24T10:30:00"
}

Error β€” 400 Validation:

{
  "name": "Name is required",
  "email": "Please provide a valid email address",
  "password": "Password must be at least 6 characters"
}

POST /api/auth/login

Authenticate and receive a JWT token.

Auth: Public

Request:

{
  "email": "shubham@example.com",
  "password": "secret123"
}

Response β€” 200 OK:

{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "email": "shubham@example.com",
  "name": "Shubham Kale",
  "role": "USER"
}

Error β€” 401:

{
  "status": 401,
  "message": "Invalid email or password",
  "timestamp": "2026-05-24T10:30:00"
}

Note: The message never reveals whether email or password was wrong. Intentional security behavior.


GET /oauth2/authorization/google

Trigger Google OAuth2 login. Open this URL in a browser. After Google authentication, returns JWT token identical to regular login response.

Auth: Public


GET /api/auth/oauth2/google/url

Get the Google OAuth2 login URL.

Auth: Public

Response β€” 200 OK:

http://localhost:8081/oauth2/authorization/google

2. Events

GET /api/events

Get all published events ordered by date.

Auth: Public | Cache: Redis (5 min TTL, evicted on write)

Response β€” 200 OK:

[
  {
    "id": 1,
    "title": "Spring Boot Hackathon",
    "description": "24-hour coding marathon for Java developers",
    "eventDate": "2026-12-01T09:00:00",
    "location": "Pune",
    "capacity": 100,
    "registrationsCount": 47,
    "spotsRemaining": 53,
    "isFull": false,
    "status": "PUBLISHED",
    "venueId": 1,
    "venue": {
      "id": 1,
      "name": "Pune Tech Park",
      "city": "Pune",
      "mapUrl": "https://www.google.com/maps?q=18.5911,73.7380"
    },
    "categoryIds": [1, 2],
    "categoryNames": ["Technology", "Education"],
    "createdAt": "2026-05-01T10:00:00"
  }
]

GET /api/events/{id}

Get a single event by ID.

Auth: Public

Response β€” 200 OK: Single event object (same structure as above)

Error β€” 404:

{
  "status": 404,
  "message": "Event not found with id: 999",
  "timestamp": "2026-05-24T10:30:00"
}

GET /api/events/search?q={query}

Fuzzy search events via Elasticsearch. Tolerates typos automatically.

Auth: Public

Example: GET /api/events/search?q=hckathon β†’ returns "Spring Boot Hackathon"

Response β€” 200 OK:

[
  {
    "id": "1",
    "title": "Spring Boot Hackathon",
    "description": "24-hour coding marathon",
    "location": "Pune",
    "eventDate": "2026-12-01T09:00:00",
    "capacity": 100,
    "categories": ["Technology", "Education"]
  }
]

GET /api/events/search/category/{category}

Filter events by exact category name using Elasticsearch.

Auth: Public

Example: GET /api/events/search/category/Technology

Response β€” 200 OK: Array of EventDocument matching the category


GET /api/events/upcoming

Get upcoming published events (future dates only).

Auth: Public

Response β€” 200 OK: Array of events ordered by eventDate ascending


GET /api/events/past

Get past published events.

Auth: Public

Response β€” 200 OK: Array of events ordered by eventDate descending


POST /api/events

Create a new event.

Auth: πŸ”’ Required

Request:

{
  "title": "Spring Boot Hackathon",
  "description": "24-hour coding marathon for Java developers",
  "eventDate": "2026-12-01T09:00:00",
  "location": "Pune",
  "capacity": 100,
  "venueId": 1,
  "categoryIds": [1, 2]
}

Response β€” 201 Created:

{
  "id": 1,
  "title": "Spring Boot Hackathon",
  "description": "24-hour coding marathon for Java developers",
  "eventDate": "2026-12-01T09:00:00",
  "location": "Pune",
  "capacity": 100,
  "registrationsCount": 0,
  "spotsRemaining": 100,
  "isFull": false,
  "status": "PUBLISHED",
  "venueId": 1,
  "venue": { "id": 1, "name": "Pune Tech Park", "city": "Pune" },
  "categoryIds": [1, 2],
  "categoryNames": ["Technology", "Education"],
  "createdAt": "2026-05-24T10:30:00"
}

Error β€” 400 Venue capacity exceeded:

{
  "status": 400,
  "message": "Event capacity 200 exceeds venue capacity 100",
  "timestamp": "2026-05-24T10:30:00"
}

PUT /api/events/{id}

Update an existing event.

Auth: πŸ”’ Required

Request: Same fields as create (all optional)

Response β€” 200 OK: Updated event object


DELETE /api/events/{id}

Delete an event.

Auth: πŸ”’ Required

Response β€” 204 No Content


POST /api/events/{id}/publish

Publish a draft event (DRAFT β†’ PUBLISHED).

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK:

{
  "id": 1,
  "title": "Spring Boot Hackathon",
  "status": "PUBLISHED",
  "publishedAt": "2026-05-24T10:30:00"
}

Error β€” 400 Invalid transition:

{
  "status": 400,
  "message": "Cannot transition event from PUBLISHED to PUBLISHED. Invalid state transition.",
  "timestamp": "2026-05-24T10:30:00"
}

POST /api/events/{id}/cancel

Cancel a published event. Notifies all registered users via Kafka.

Auth: πŸ”’ Required (organizer or admin)

Request (optional):

{
  "cancellationReason": "Venue unavailable due to unforeseen circumstances"
}

Response β€” 200 OK:

{
  "id": 1,
  "status": "CANCELLED",
  "cancelledAt": "2026-05-24T10:30:00",
  "cancellationReason": "Venue unavailable due to unforeseen circumstances"
}

POST /api/events/{id}/complete

Mark a published event as completed. Enables reviews.

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK: Event with "status": "COMPLETED"


POST /api/events/reindex

Re-sync all MySQL events to Elasticsearch index.

Auth: Public

Response β€” 200 OK: "Reindexed successfully"


3. Venues

GET /api/venues

Get all venues.

Auth: Public

Response β€” 200 OK:

[
  {
    "id": 1,
    "name": "Pune Tech Park",
    "address": "Hinjewadi Phase 1",
    "city": "Pune",
    "state": "Maharashtra",
    "pincode": "411057",
    "capacity": 500,
    "mapUrl": "https://www.google.com/maps?q=18.5911527,73.7380007",
    "createdAt": "2026-05-01T10:00:00"
  }
]

Note: latitude and longitude are stored internally for location-based search but never returned in API responses. mapUrl is provided for human-friendly map access.


GET /api/venues/{id}

Get venue by ID.

Auth: Public


GET /api/venues/city/{city}

Filter venues by city (case-insensitive).

Auth: Public

Example: GET /api/venues/city/pune or GET /api/venues/city/Pune β€” same result


GET /api/venues/capacity/{min}

Find venues with capacity β‰₯ min.

Auth: Public

Example: GET /api/venues/capacity/200 β€” returns venues that hold 200+ people


POST /api/venues

Create a venue. Coordinates are auto-geocoded from address.

Auth: πŸ”’ Required

Request (without coordinates β€” auto-geocoded):

{
  "name": "Koregaon Park Venue",
  "address": "Koregaon Park",
  "city": "Pune",
  "state": "Maharashtra",
  "pincode": "411001",
  "capacity": 300
}

Request (with manual coordinates):

{
  "name": "Koregaon Park Venue",
  "address": "Koregaon Park",
  "city": "Pune",
  "capacity": 300,
  "latitude": 18.5366225,
  "longitude": 73.8932738
}

Response β€” 201 Created:

{
  "id": 2,
  "name": "Koregaon Park Venue",
  "address": "Koregaon Park",
  "city": "Pune",
  "state": "Maharashtra",
  "capacity": 300,
  "mapUrl": "https://www.google.com/maps?q=18.5366225,73.8932738",
  "createdAt": "2026-05-24T10:30:00"
}

PUT /api/venues/{id}

Update a venue.

Auth: πŸ”’ Required


DELETE /api/venues/{id}

Delete a venue. Sets venue_id = NULL on associated events (events are preserved).

Auth: πŸ”’ Required

Response β€” 204 No Content


POST /api/venues/{id}/regeocoding

Retry coordinate lookup for a venue with null coordinates.

Auth: πŸ”’ Required

Response β€” 200 OK: Updated venue with coordinates populated


4. Organizations

GET /api/organizations

Get all organizations (summary view).

Auth: Public

Response β€” 200 OK:

[
  {
    "id": 1,
    "name": "Pune Java User Group",
    "location": "Pune",
    "followerCount": 245
  }
]

GET /api/organizations/{id}

Get full organization details.

Auth: Public

Response β€” 200 OK:

{
  "id": 1,
  "name": "Pune Java User Group",
  "description": "Monthly Java meetups and workshops in Pune",
  "website": "https://pjug.in",
  "location": "Pune",
  "ownerId": 1,
  "ownerName": "Shubham Kale",
  "followerCount": 245,
  "isFollowing": false,
  "createdAt": "2026-01-15T10:00:00"
}

isFollowing reflects the current authenticated user's follow status. Returns false for unauthenticated requests.


POST /api/organizations

Create an organization. The authenticated user becomes the owner.

Auth: πŸ”’ Required

Request:

{
  "name": "Pune Java User Group",
  "description": "Monthly Java meetups and workshops in Pune",
  "website": "https://pjug.in",
  "location": "Pune"
}

Response β€” 201 Created: Full organization object

Error β€” 400 Duplicate:

{
  "status": 400,
  "message": "Organization already exists: Pune Java User Group",
  "timestamp": "2026-05-24T10:30:00"
}

PUT /api/organizations/{id}

Update organization. Owner only.

Auth: πŸ”’ Required (owner only)

Error β€” 403:

{
  "status": 403,
  "message": "Only the owner can update this organization",
  "timestamp": "2026-05-24T10:30:00"
}

DELETE /api/organizations/{id}

Delete organization. Owner or admin only.

Auth: πŸ”’ Required (owner or admin)

Response β€” 204 No Content


POST /api/organizations/{id}/follow

Follow an organization.

Auth: πŸ”’ Required

Response β€” 200 OK: "Following organization"

Error β€” 400 Own organization:

{
  "status": 400,
  "message": "Cannot follow your own organization",
  "timestamp": "2026-05-24T10:30:00"
}

DELETE /api/organizations/{id}/follow

Unfollow an organization.

Auth: πŸ”’ Required

Response β€” 200 OK: "Unfollowed organization"


GET /api/organizations/my

Get organizations created by the current user.

Auth: πŸ”’ Required

Response β€” 200 OK: Array of OrganizationSummaryDTO


GET /api/organizations/following

Get organizations the current user follows, ordered by follow date.

Auth: πŸ”’ Required

Response β€” 200 OK: Array of OrganizationSummaryDTO


5. User Profile

GET /api/users/me

Get current user's profile.

Auth: πŸ”’ Required

Response β€” 200 OK:

{
  "id": 1,
  "name": "Shubham Kale",
  "email": "shubham@example.com",
  "bio": "Java backend developer from Pune",
  "phone": "9876543210",
  "city": "Pune",
  "role": "USER",
  "createdAt": "2026-01-01T10:00:00",
  "updatedAt": "2026-05-24T10:30:00"
}

PUT /api/users/me

Update profile. Email and role are read-only and cannot be changed here.

Auth: πŸ”’ Required

Request:

{
  "name": "Shubham Kale",
  "bio": "Java backend developer from Pune",
  "phone": "9876543210",
  "city": "Pune"
}

Response β€” 200 OK: Updated profile object


PUT /api/users/me/password

Change password. Requires current password verification.

Auth: πŸ”’ Required

Request:

{
  "currentPassword": "oldpassword",
  "newPassword": "newpassword123",
  "confirmPassword": "newpassword123"
}

Response β€” 200 OK: "Password changed successfully"

Error β€” 400 Wrong current password:

{
  "status": 400,
  "message": "Current password is incorrect",
  "timestamp": "2026-05-24T10:30:00"
}

DELETE /api/users/me

Permanently delete account.

Auth: πŸ”’ Required

Response β€” 200 OK: "Account deleted successfully"


6. Categories

GET /api/categories

Get all categories ordered by event count descending.

Auth: Public

Response β€” 200 OK:

[
  {
    "id": 1,
    "name": "Technology",
    "description": "Software, hardware, and tech events",
    "icon": "laptop",
    "eventCount": 47,
    "createdAt": "2026-01-01T00:00:00"
  },
  {
    "id": 2,
    "name": "Education",
    "description": "Workshops, seminars, and learning events",
    "icon": "book",
    "eventCount": 23,
    "createdAt": "2026-01-01T00:00:00"
  }
]

10 categories are pre-seeded: Technology, Education, Business, Music, Sports, Arts, Food, Health, Social, Other


GET /api/categories/{id}

Get category by ID.

Auth: Public


GET /api/categories/event/{eventId}

Get all categories for a specific event.

Auth: Public


POST /api/categories

Create a new category. Admin only.

Auth: πŸ”’ ADMIN role required

Request:

{
  "name": "Gaming",
  "description": "Gaming tournaments and community events",
  "icon": "gamepad"
}

Response β€” 201 Created: Category object


PUT /api/categories/{id}

Update a category. Admin only.

Auth: πŸ”’ ADMIN role required


DELETE /api/categories/{id}

Delete a category. Admin only.

Auth: πŸ”’ ADMIN role required

Response β€” 204 No Content


7. Event Registration

POST /api/events/{id}/register

Register for an event. Uses atomic SQL to prevent overselling under concurrent load.

Auth: πŸ”’ Required

Response β€” 200 OK:

{
  "id": 1,
  "eventId": 1,
  "eventTitle": "Spring Boot Hackathon",
  "eventLocation": "Pune",
  "eventDate": "2026-12-01T09:00:00",
  "userId": 1,
  "userName": "Shubham Kale",
  "userEmail": "shubham@example.com",
  "status": "CONFIRMED",
  "registeredAt": "2026-05-24T10:30:00",
  "cancelledAt": null
}

Error β€” 400 Event full:

{
  "status": 400,
  "message": "Event is full. No spots remaining.",
  "timestamp": "2026-05-24T10:30:00"
}

Error β€” 400 Already registered:

{
  "status": 400,
  "message": "Already registered for this event",
  "timestamp": "2026-05-24T10:30:00"
}

Error β€” 400 Past event:

{
  "status": 400,
  "message": "Cannot register for a past event",
  "timestamp": "2026-05-24T10:30:00"
}

DELETE /api/events/{id}/register

Cancel registration. Frees up spot atomically. Auto-promotes first waitlisted user.

Auth: πŸ”’ Required

Response β€” 200 OK: "Registration cancelled"


GET /api/events/my-registrations

Get all events the current user registered for.

Auth: πŸ”’ Required

Response β€” 200 OK: Array of RegistrationDTO ordered by registration date


GET /api/events/{id}/registrations

Get all confirmed attendees for an event. Organizer or admin only.

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK: Array of RegistrationDTO (CONFIRMED only)

Error β€” 403:

{
  "status": 403,
  "message": "Only the event organizer or admin can view attendees",
  "timestamp": "2026-05-24T10:30:00"
}

GET /api/events/{id}/registration-status

Check if current user is registered for this event.

Auth: πŸ”’ Required

Response β€” 200 OK: true or false


GET /api/events/{id}/spots-remaining

Get number of confirmed registrations (public).

Auth: Public

Response β€” 200 OK: 47 (number)


8. Waitlist

POST /api/events/{id}/waitlist

Join the waitlist for a full event.

Auth: πŸ”’ Required

Response β€” 200 OK:

{
  "id": 1,
  "eventId": 1,
  "eventTitle": "Spring Boot Hackathon",
  "userId": 3,
  "userName": "Test User Three",
  "position": 1,
  "status": "WAITING",
  "joinedAt": "2026-05-24T10:30:00"
}

Error β€” 400 Event not full:

{
  "status": 400,
  "message": "Event is not full. Register directly instead.",
  "timestamp": "2026-05-24T10:30:00"
}

DELETE /api/events/{id}/waitlist

Leave the waitlist.

Auth: πŸ”’ Required

Response β€” 200 OK: "Left waitlist"


GET /api/events/{id}/waitlist

View waitlist for an event (ordered by position).

Auth: πŸ”’ Required

Response β€” 200 OK: Array of WaitlistDTO ordered by position


GET /api/events/my-waitlist

Get all events current user is waitlisted for.

Auth: πŸ”’ Required

Response β€” 200 OK: Array of WaitlistDTO


9. Reviews & Ratings

POST /api/events/{id}/reviews

Submit a review. Three guards: event must be COMPLETED, user must have registered, one review per event.

Auth: πŸ”’ Required

Request:

{
  "rating": 5,
  "comment": "Excellent event! The Spring Boot sessions were incredibly insightful."
}

Response β€” 201 Created:

{
  "id": 1,
  "eventId": 1,
  "eventTitle": "Spring Boot Hackathon",
  "userId": 1,
  "userName": "Shubham Kale",
  "rating": 5,
  "comment": "Excellent event! The Spring Boot sessions were incredibly insightful.",
  "createdAt": "2026-05-24T10:30:00",
  "updatedAt": null
}

Error β€” 400 Event not completed:

{
  "status": 400,
  "message": "Reviews are only allowed for completed events. Event status is: PUBLISHED",
  "timestamp": "2026-05-24T10:30:00"
}

Error β€” 400 Not registered:

{
  "status": 400,
  "message": "You can only review events you registered for",
  "timestamp": "2026-05-24T10:30:00"
}

GET /api/events/{id}/reviews

Get all reviews for an event.

Auth: Public

Response β€” 200 OK: Array of ReviewDTO ordered by newest first


GET /api/events/{id}/rating

Get average rating and review count.

Auth: Public

Response β€” 200 OK:

{
  "eventId": 1,
  "averageRating": 4.7,
  "totalReviews": 23
}

PUT /api/events/reviews/{reviewId}

Update a review. Owner only.

Auth: πŸ”’ Required (review owner only)

Request:

{
  "rating": 4,
  "comment": "Updated: Great event, minor logistics issues."
}

DELETE /api/events/reviews/{reviewId}

Delete a review. Owner or admin.

Auth: πŸ”’ Required (review owner or admin)

Response β€” 204 No Content


GET /api/events/my-reviews

Get all reviews submitted by current user.

Auth: πŸ”’ Required


10. Bookmarks

POST /api/events/{id}/bookmark

Bookmark an event.

Auth: πŸ”’ Required

Response β€” 200 OK: "Event bookmarked"


DELETE /api/events/{id}/bookmark

Remove bookmark.

Auth: πŸ”’ Required

Response β€” 200 OK: "Bookmark removed"


GET /api/events/bookmarks

Get all bookmarked events for current user.

Auth: πŸ”’ Required

Response β€” 200 OK: Array of EventDTO


GET /api/events/{id}/bookmark-status

Check if event is bookmarked by current user.

Auth: πŸ”’ Required

Response β€” 200 OK: true or false


11. Notifications

GET /api/notifications

Get all notifications for current user, ordered newest first.

Auth: πŸ”’ Required

Response β€” 200 OK:

[
  {
    "id": 1,
    "type": "EVENT_CANCELLED",
    "title": "Event Cancelled",
    "message": "The event 'Spring Boot Hackathon' you registered for has been cancelled. Reason: Venue unavailable.",
    "isRead": false,
    "entityType": "EVENT",
    "entityId": 1,
    "createdAt": "2026-05-24T10:30:00",
    "readAt": null
  },
  {
    "id": 2,
    "type": "REGISTRATION_CONFIRMED",
    "title": "Registration Confirmed",
    "message": "You are registered for 'Java Workshop'. See you there!",
    "isRead": true,
    "entityType": "EVENT",
    "entityId": 2,
    "createdAt": "2026-05-23T14:00:00",
    "readAt": "2026-05-23T14:05:00"
  }
]

Notification types: EVENT_CANCELLED, EVENT_UPDATED, REGISTRATION_CONFIRMED, REGISTRATION_CANCELLED, NEW_FOLLOWER, NEW_EVENT_FROM_FOLLOWED_ORG, ROLE_CHANGED, WELCOME


GET /api/notifications/unread

Get only unread notifications.

Auth: πŸ”’ Required


GET /api/notifications/unread-count

Get unread notification count (lightweight β€” for badge display).

Auth: πŸ”’ Required

Response β€” 200 OK: 3 (number)


PUT /api/notifications/{id}/read

Mark a single notification as read.

Auth: πŸ”’ Required

Response β€” 200 OK: "Marked as read"


PUT /api/notifications/read-all

Mark all notifications as read. Uses single bulk UPDATE query.

Auth: πŸ”’ Required

Response β€” 200 OK: "All notifications marked as read"


DELETE /api/notifications/{id}

Delete a notification.

Auth: πŸ”’ Required (notification owner only)

Response β€” 204 No Content


12. Dashboard & Analytics

GET /api/dashboard/organizer

Get dashboard for all events owned by current user's organizations.

Auth: πŸ”’ Required

Response β€” 200 OK:

{
  "totalEventsCreated": 12,
  "publishedEvents": 5,
  "cancelledEvents": 2,
  "completedEvents": 5,
  "totalRegistrations": 347,
  "totalUniqueAttendees": 298,
  "averageRatingAcrossEvents": 4.3,
  "eventBreakdown": [
    {
      "eventId": 1,
      "eventTitle": "Spring Boot Hackathon",
      "status": "PUBLISHED",
      "capacity": 100,
      "confirmedRegistrations": 47,
      "cancelledRegistrations": 3,
      "spotsRemaining": 53,
      "averageRating": 4.8,
      "totalReviews": 12,
      "registrationRate": 47.0
    }
  ]
}

GET /api/dashboard/admin

Platform-wide statistics. Admin only.

Auth: πŸ”’ ADMIN role required

Response β€” 200 OK:

{
  "totalEvents": 156,
  "publishedEvents": 89,
  "totalUsers": 1247,
  "totalOrganizations": 34
}

GET /api/dashboard/events/{id}/analytics

Detailed analytics for a specific event.

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK:

{
  "eventId": 1,
  "eventTitle": "Spring Boot Hackathon",
  "status": "COMPLETED",
  "capacity": 100,
  "confirmedRegistrations": 94,
  "cancelledRegistrations": 6,
  "spotsRemaining": 0,
  "averageRating": 4.7,
  "totalReviews": 31,
  "registrationRate": 94.0
}

13. Export

GET /api/events/{id}/attendees/export?format=csv

Download confirmed attendee list as CSV.

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK:

Content-Disposition: attachment; filename="Spring Boot Hackathon-attendees.csv"
Content-Type: text/csv

Name,Email,Registered At,Status
Shubham Kale,shubham@example.com,2026-05-01T10:00:00,CONFIRMED
...

GET /api/events/{id}/attendees/export?format=excel

Download confirmed attendee list as Excel (.xlsx).

Auth: πŸ”’ Required (organizer or admin)

Response β€” 200 OK:

Content-Disposition: attachment; filename="Spring Boot Hackathon-attendees.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Formatted Excel with bold headers and auto-sized columns.


14. Admin

GET /api/admin/users

List all registered users with roles.

Auth: πŸ”’ ADMIN role required

Response β€” 200 OK:

[
  "shubham@example.com β€” USER",
  "admin@events.com β€” ADMIN",
  "user2@example.com β€” USER"
]

PUT /api/admin/users/{email}/promote

Promote a USER to ADMIN role.

Auth: πŸ”’ ADMIN role required

Response β€” 200 OK: "shubham@example.com has been promoted to ADMIN"


PUT /api/admin/users/{email}/demote

Demote an ADMIN to USER role.

Auth: πŸ”’ ADMIN role required

Response β€” 200 OK: "shubham@example.com has been demoted to USER"


15. AI Recommendations

GET /api/ai/recommend?interests={interests}

Get AI-powered event recommendations. Powered by Spring AI β€” provider-agnostic (Groq LLaMA 3, Anthropic Claude, OpenAI GPT, local Ollama).

Auth: πŸ”’ Required

Example: GET /api/ai/recommend?interests=backend development and Java

Response β€” 200 OK:

Based on your interest in backend development and Java, here are my top picks:

1. Spring Boot Hackathon (Pune Tech Park, Dec 1) β€” Perfect match! This 24-hour
   coding marathon focuses on Java backend development, giving you hands-on
   experience in a competitive environment.

2. Java Workshop (Mumbai, Nov 15) β€” Great for strengthening your Java
   fundamentals which is the foundation of all the backend work you enjoy.

16. System

GET /api/system/health

Custom health check verifying all infrastructure dependencies.

Auth: Public

Response β€” 200 OK (all healthy):

{
  "status": "UP",
  "application": "UP",
  "mysql": "UP",
  "redis": "UP",
  "timestamp": "2026-05-24T10:30:00"
}

Response β€” 200 OK (degraded):

{
  "status": "DEGRADED",
  "application": "UP",
  "mysql": "UP",
  "redis": "DOWN",
  "redisError": "Connection refused",
  "timestamp": "2026-05-24T10:30:00"
}

GET /api/system/version

Get application version and runtime info.

Auth: Public

Response β€” 200 OK:

{
  "application": "Event Management System",
  "version": "4.0.0",
  "phase": "Phase 5 β€” Cloud Ready",
  "java": "17.0.9",
  "springBoot": "3.4.1"
}

17. Error Reference

Standard Error Format

All errors follow this structure:

{
  "status": 404,
  "message": "Descriptive error message",
  "timestamp": "2026-05-24T10:30:00"
}

Validation Error Format

{
  "fieldName": "Validation message",
  "anotherField": "Another validation message"
}

HTTP Status Codes

Code Meaning When
200 OK Successful GET, PUT, action endpoints
201 Created Resource created via POST
204 No Content Successful DELETE
400 Bad Request Validation failed, business rule violated
401 Unauthorized No token, invalid/expired token
403 Forbidden Authenticated but insufficient permissions
404 Not Found Resource does not exist
429 Too Many Requests Rate limit exceeded (20 req/IP)
500 Internal Server Error Unexpected server error

Rate Limiting

All endpoints are rate-limited to 20 requests per IP. Tokens refill at 10/second.

429 Response:

{
  "status": 429,
  "message": "Too many requests. Slow down."
}

Kafka Topics

Topic Producer Consumer Payload
event.cancelled Main App Email Service EventCancelledMessage
event.registered Main App Email Service EventRegisteredMessage
email.requested Main App Email Service Generic email request

Swagger UI

Interactive documentation with executable requests:

http://localhost:8081/swagger-ui/index.html

Click Authorize β†’ paste JWT token β†’ all protected endpoints execute from browser.

Raw OpenAPI spec: http://localhost:8081/api-docs


Event Management System β€” Production Ready | Built by Shubham Kale

Clone this wiki locally