Skip to content
Shubham Kale edited this page May 5, 2026 · 3 revisions

API Documentation β€” Event Management System

Complete reference for all endpoints, request formats, response formats, and error codes.


Base URL

http://localhost:8081

Authentication

Most endpoints require a JWT token. Get one by registering or logging in.

Header format for all protected requests:

Authorization: Bearer <your-jwt-token>

Token details:

  • Algorithm: HS256
  • Expiry: 24 hours
  • Stateless β€” no server-side sessions

Table of Contents


Authentication Endpoints

Register

Creates a new user account and returns a JWT token.

POST /api/auth/register

Request Body

Field Type Required Validation
name String Yes Not blank
email String Yes Valid email format
password String Yes Minimum 6 characters

Example Request

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

Example Response β€” 200 OK

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

Error β€” 400 Validation Failed

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

Error β€” 400 Duplicate Email

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

Login

Authenticates an existing user and returns a JWT token.

POST /api/auth/login

Request Body

Field Type Required
email String Yes
password String Yes

Example Request

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

Example Response β€” 200 OK

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

Error β€” 401 Wrong Credentials

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

Note: The error message never reveals whether the email or password was wrong. This is intentional security behavior.


Event Endpoints

Get All Events

Returns all events. Result is cached in Redis. Second call onwards is served from cache without hitting the database.

GET /api/events

Auth: Public β€” no token required

Example Response β€” 200 OK

[
    {
        "id": 1,
        "title": "Spring Boot Hackathon",
        "description": "A 24 hour coding event for Java developers",
        "eventDate": "2026-12-01T09:00:00",
        "location": "Pune",
        "capacity": 100,
        "createdAt": "2026-04-21T16:04:06"
    },
    {
        "id": 2,
        "title": "Java Workshop",
        "description": "Learn core Java concepts",
        "eventDate": "2026-11-15T10:00:00",
        "location": "Mumbai",
        "capacity": 50,
        "createdAt": "2026-04-21T16:10:00"
    }
]

Empty list response β€” 200 OK

[]

Get Event By ID

Returns a single event by its ID. Result is cached individually in Redis.

GET /api/events/{id}

Auth: Public β€” no token required

Path Parameters

Parameter Type Description
id Long Event ID

Example Request

GET /api/events/1

Example Response β€” 200 OK

{
    "id": 1,
    "title": "Spring Boot Hackathon",
    "description": "A 24 hour coding event for Java developers",
    "eventDate": "2026-12-01T09:00:00",
    "location": "Pune",
    "capacity": 100,
    "createdAt": "2026-04-21T16:04:06"
}

Error β€” 404 Not Found

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

Create Event

Creates a new event. Saves to MySQL, indexes in Elasticsearch, evicts Redis cache, and sends confirmation email asynchronously.

POST /api/events

Auth: πŸ”’ Required β€” Bearer token

Query Parameters

Parameter Type Required Description
userEmail String No Email for confirmation (default: admin@events.com)

Request Body

Field Type Required Validation
title String Yes Not blank
description String No Max 1000 characters
eventDate LocalDateTime Yes Must be future date
location String No β€”
capacity Integer No Minimum 1

Example Request

POST /api/events?userEmail=organizer@example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
{
    "title": "Spring Boot Hackathon",
    "description": "A 24 hour coding event for Java developers",
    "eventDate": "2026-12-01T09:00:00",
    "location": "Pune",
    "capacity": 100
}

Example Response β€” 201 Created

{
    "id": 1,
    "title": "Spring Boot Hackathon",
    "description": "A 24 hour coding event for Java developers",
    "eventDate": "2026-12-01T09:00:00",
    "location": "Pune",
    "capacity": 100,
    "createdAt": "2026-04-25T10:30:00"
}

Error β€” 400 Validation Failed

{
    "title": "Title cannot be empty",
    "eventDate": "Event date cannot be in the past",
    "capacity": "Capacity cannot be less than 1"
}

Error β€” 401 No Token

{
    "status": 401,
    "message": "Unauthorized",
    "timestamp": "2026-04-25T10:30:00"
}

Update Event

Updates an existing event. Also updates the Elasticsearch index and evicts Redis cache.

PUT /api/events/{id}

Auth: πŸ”’ Required β€” Bearer token

Path Parameters

Parameter Type Description
id Long Event ID to update

Request Body β€” same fields as Create Event

Example Request

PUT /api/events/1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
{
    "title": "Updated Hackathon 2026",
    "description": "Updated description",
    "eventDate": "2026-12-15T09:00:00",
    "location": "Mumbai",
    "capacity": 200
}

Example Response β€” 200 OK

{
    "id": 1,
    "title": "Updated Hackathon 2026",
    "description": "Updated description",
    "eventDate": "2026-12-15T09:00:00",
    "location": "Mumbai",
    "capacity": 200,
    "createdAt": "2026-04-25T10:30:00"
}

Error β€” 404 Not Found

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

Delete Event

Deletes an event from MySQL and removes it from the Elasticsearch index. Evicts Redis cache.

DELETE /api/events/{id}

Auth: πŸ”’ Required β€” Bearer token

Path Parameters

Parameter Type Description
id Long Event ID to delete

Example Request

DELETE /api/events/1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

Response β€” 204 No Content

No body returned on successful deletion.

Error β€” 404 Not Found

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

Search Events

Searches events using Elasticsearch with fuzzy matching. Tolerates typos automatically. Searches across title (weighted 3x), description, and location fields.

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

Auth: Public β€” no token required

Query Parameters

Parameter Type Required Description
q String Yes Search query β€” typos allowed

Fuzziness behavior:

  • Words 1-2 characters: exact match required
  • Words 3-5 characters: 1 character edit allowed
  • Words 6+ characters: 2 character edits allowed

Example Request β€” exact search

GET /api/events/search?q=hackathon

Example Request β€” typo search

GET /api/events/search?q=hckathon

Both return the same result:

Example Response β€” 200 OK

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

Empty search result β€” 200 OK

[]

Note: Search returns EventDocument objects from Elasticsearch, not EventDTO objects from MySQL. The id field is a String in Elasticsearch vs Long in MySQL.


Reindex Events

Syncs all events from MySQL into Elasticsearch. Call this once if you have events created before Elasticsearch was added.

POST /api/events/reindex

Auth: Public

Response β€” 200 OK

Reindexed successfully

Admin Endpoints

All admin endpoints require a JWT token belonging to a user with ADMIN role. Regular USER tokens receive 403 Forbidden.

Default admin credentials:

Email:    admin@events.com
Password: admin123

Get All Users

Returns a list of all registered users with their roles.

GET /api/admin/users

Auth: πŸ”’ ADMIN role required

Example Response β€” 200 OK

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

Error β€” 403 Forbidden (USER token)

{
    "status": 403,
    "message": "Access Denied",
    "timestamp": "2026-04-25T10:30:00"
}

Promote to Admin

Promotes a USER to ADMIN role. The user must already be registered.

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

Auth: πŸ”’ ADMIN role required

Path Parameters

Parameter Type Description
email String Email of user to promote

Example Request

PUT /api/admin/users/jane@example.com/promote
Authorization: Bearer <ADMIN token>

Response β€” 200 OK

jane@example.com has been promoted to ADMIN

Error β€” 404 User Not Found

{
    "status": 404,
    "message": "User not found: jane@example.com",
    "timestamp": "2026-04-25T10:30:00"
}

Demote to User

Demotes an ADMIN back to USER role.

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

Auth: πŸ”’ ADMIN role required

Example Request

PUT /api/admin/users/jane@example.com/demote
Authorization: Bearer <ADMIN token>

Response β€” 200 OK

jane@example.com has been demoted to USER

AI Endpoints

Get Recommendations

Returns personalized event recommendations based on user interests. Powered by AI via Spring AI abstraction. Works with Groq (free), Anthropic Claude, OpenAI, or Ollama depending on configuration.

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

Auth: πŸ”’ Required β€” Bearer token

Query Parameters

Parameter Type Required Description
interests String Yes Describe your interests

Example Request

GET /api/ai/recommend?interests=backend development and Java
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

Example Response β€” 200 OK

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

1. Spring Boot Hackathon (Pune, Dec 1) β€” Perfect match! This 24-hour 
   coding marathon focuses on Java and Spring Boot, giving you hands-on 
   backend development 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.

Error Reference

All error responses follow this format:

{
    "status": 404,
    "message": "Descriptive error message here",
    "timestamp": "2026-04-25T10:30:00"
}

Validation errors return field-level details:

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

Organization Endpoints

Organizations are groups that host events. Examples: "Pune Java User Group", "Google Developer Group Pune", "HSBC Tech Team".

⚠️ Note: Organization endpoints are implemented but not fully tested yet. Treat as beta.

Get All Organizations

GET /api/organizations

Auth: Public

Response β€” 200 OK

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

Returns OrganizationSummaryDTO β€” lightweight response for list views.


Get Organization By ID

Returns full organization details including owner info and follower count.

GET /api/organizations/{id}

Auth: Public

Response β€” 200 OK

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

isFollowing is false when called without auth token. When called with token, reflects actual follow status of current user.


Create Organization

POST /api/organizations

Auth: πŸ”’ Required

Request Body

Field Type Required Validation
name String Yes Not blank, must be unique
description String No Max 1000 chars
website String No β€”
location String No β€”

Example Request

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

Response β€” 201 Created

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

Error β€” 400 Duplicate Name

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

Update Organization

Only the owner can update their organization.

PUT /api/organizations/{id}

Auth: πŸ”’ Required (Owner only)

Same request body as Create Organization.

Error β€” 403 Not Owner

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

Delete Organization

Owner or ADMIN can delete an organization.

DELETE /api/organizations/{id}

Auth: πŸ”’ Required (Owner or ADMIN)

Response β€” 204 No Content

Error β€” 403 Not Owner or Admin

{
    "status": 403,
    "message": "Only the owner or admin can delete this organization",
    "timestamp": "2026-05-04T10:30:00"
}

Follow Organization

POST /api/organizations/{id}/follow

Auth: πŸ”’ Required

Response β€” 200 OK: Following organization

Error β€” 400 Already Following

{
    "status": 400,
    "message": "Already following this organization",
    "timestamp": "2026-05-04T10:30:00"
}

Error β€” 400 Own Organization

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

Unfollow Organization

DELETE /api/organizations/{id}/follow

Auth: πŸ”’ Required

Response β€” 200 OK: Unfollowed organization

Error β€” 400 Not Following

{
    "status": 400,
    "message": "Not following this organization",
    "timestamp": "2026-05-04T10:30:00"
}

Get My Organizations

Returns organizations created by the current user.

GET /api/organizations/my

Auth: πŸ”’ Required

Response β€” 200 OK β€” array of OrganizationSummaryDTO


Get Followed Organizations

Returns organizations the current user follows.

GET /api/organizations/following

Auth: πŸ”’ Required

Response β€” 200 OK β€” array of OrganizationSummaryDTO ordered by follow date descending


Status Codes

Code Meaning When
200 OK Successful GET, PUT, LOGIN
201 Created Successful POST (event created)
204 No Content Successful DELETE
400 Bad Request Validation failed, duplicate email
401 Unauthorized No token, invalid token, wrong password
403 Forbidden Valid token but wrong role
404 Not Found Event or user does not exist
429 Too Many Requests Rate limit exceeded (20 req/IP)
500 Internal Server Error Unexpected server error

Rate Limiting

Every IP address is limited to 20 requests. Tokens refill at 10 per second.

When rate limited:

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

Wait 2 seconds and retry.


Swagger UI

Interactive documentation where you can execute requests directly in the browser:

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

Click Authorize at the top right, paste your JWT token, and all protected endpoints work directly from the browser.

Raw OpenAPI JSON spec:

http://localhost:8081/api-docs

Date Format

All date fields use ISO 8601 format:

yyyy-MM-dd'T'HH:mm:ss

Example:

2026-12-01T09:00:00

Event Management System β€” Phase 4 complete. Phase 5 adds Docker, Kafka, and observability.

Clone this wiki locally