Powered By SWAGGER

Venue API

REST API powering real-time event & movie booking with ACID transactions, WebSocket updates, and Redis-backed caching.

OpenAPI 3.0 JWT + httpOnly Cookies 6-Tier Rate Limiting Real-Time Socket.io

Platform Overview

Venue is a full-stack booking platform engineered to handle concurrent reservations, real-time seat inventory, and multi-tenant event management — without overselling a single ticket.

7
API Modules
30+
REST Endpoints
6
Rate Limit Tiers
ACID
Transaction Safety

Core Capabilities

🎫

Event & Movie Booking

Full lifecycle — create events/movies, manage time slots, bookings with seat selection and atomic capacity control.

Pessimistic Concurrency

MongoDB ACID transactions with atomic findOneAndUpdate + $inc prevent double-bookings under concurrent load.

🔌

Real-Time WebSocket

Socket.io delivers instant waitlist notifications — users get promoted the moment a seat frees up.

🗄️

Redis Caching

Cache-aside on all GET endpoints with 60s TTL, automatic invalidation on mutations, fail-open degradation.

🛡️

6-Tier Rate Limiting

Context-aware, Redis-backed — from global DDoS shield (1000/hr) to booking burst guard (5/min).

🏢

Multi-Tenant Organizer

Full dashboard: event/movie CRUD, slot management with overlap detection, auto-generation, analytics.

Tech Stack

LayerTechnologyPurpose
RuntimeNode.js ExpressHTTP server & routing
DatabaseMongoDB MongooseACID transactions + data layer
CacheRedis ioredisCaching + rate limit state
Real-TimeSocket.ioWebSocket for waitlist events
AuthJWT Argon2idStateless auth + secure hashing
ValidationZodRuntime type-safe validation
StorageCloudinaryImage uploads (5 MB max)
LoggingWinstonStructured logs with redaction
TestingJest k6Unit, integration & load testing
DeployDockerContainerized production

Quick Start

Get up and running in three steps. All endpoints return standardized JSON responses.

1 — Register

bash
curl -X POST {{BASE_URL}}/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{ "name": "John Doe", "email": "john@example.com", "password": "securePass123", "role": "USER" }'
Response — 201
{ "statusCode": 201, "status": "success", "data": { "_id": "65a...", "name": "John Doe", "role": "USER" } }
💡 Cookie Auth

On success, server sets httpOnly cookie token (7‑day). Also supports Authorization: Bearer <token> header.

2 — Browse Events

bash
# Public — no auth required
curl {{BASE_URL}}/api/v1/events?page=1&limit=10&sort=-startDate

# With filters
curl {{BASE_URL}}/api/v1/events?category=Music&price[lte]=500&fields=title,price,location

3 — Book a Slot

bash
curl -X POST {{BASE_URL}}/api/v1/bookings \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "slotId": "65a1...", "quantity": 2, "seats": ["A1", "A2"] }'
⚠️ Slot Full?

Auto-waitlisted. You'll get a waitlist:promoted Socket.io event when a seat opens.

4 — Check Bookings

bash
curl {{BASE_URL}}/api/v1/bookings/my-bookings \
  -H "Authorization: Bearer YOUR_TOKEN"

Authentication

JWT-based auth with httpOnly cookie transport. Passwords hashed with Argon2id.

Token Flow

1Register / Login
2JWT in httpOnly cookie
3Cookie sent auto
4Server verifies
5Logout clears
PropertyValue
TokenJWT (HS256), 7-day expiry
Payload{ userId, role }
TransporthttpOnly cookie + Bearer header
Cookie FlagshttpOnly · secure (prod) · sameSite: none (prod)
HashingArgon2id — 64 MB, 3 iter, 4 threads

Endpoints

MethodEndpointAuthDescription
POST/api/v1/auth/registerNoRegister. Body: name, email, password, role?
POST/api/v1/auth/loginNoLogin. Sets httpOnly cookie.
GET/api/v1/auth/logoutYesClears auth cookie.
GET/api/v1/auth/meYesCurrent user profile.

Roles

👤 USER

Browse, book, manage favorites, view bookings, update profile.

🏢 ORGANIZER

+ create/edit/publish events & movies, manage slots, analytics.

🔑 ADMIN

Full access — all resources and organizer features.

Code Examples

JavaScript
const res = await axios.post('/api/v1/auth/login', {
  email: 'john@example.com', password: 'securePass123'
}, { withCredentials: true });
// Cookie set — all subsequent requests auto-authenticated
Python
s = requests.Session()
s.post('https://venue-z8ti.onrender.com/api/v1/auth/login',
       json={'email': 'john@example.com', 'password': 'securePass123'})
s.get('https://venue-z8ti.onrender.com/api/v1/bookings/my-bookings')

System Architecture

Layered architecture with clear separation of concerns.

React + Vite Frontend
Nginx Reverse Proxy
Express.js API
Socket.io Server
Helmet · CORS · Sanitize · RateLimit
MongoDB (Txn)
Redis (Cache)
Cloudinary

Request Lifecycle

1Request
2Helmet/CORS
3Request ID
4Rate Limit
5Sanitize
6JWT
7Cache
8Controller
9Response

Booking Concurrency

Atomic Seat Reservation
// Single atomic op — check + decrement
const slot = await Slot.findOneAndUpdate(
  { _id: slotId, availableSeats: { $gte: quantity } },
  { $inc: { availableSeats: -quantity } },
  { new: true, session }
);
// null → auto-waitlist + emit 'waitlist:added'
No Overselling

The $gte + $inc execute atomically. MongoDB serializes concurrent ops — 100 users, 10 seats, 0 oversells.

Rate Limiting

Six-tier, Redis-backed system with graceful degradation.

TierNameLimitWindowKeyApplies To
1Global Shield1,0001 hrIPAll auth routes
2Auth Brute Force1015 minIP/auth/*
3Scrape Protection3,0001 hrIPPublic GETs
4Per-User2001 hrUser IDAuth routes
5Write Throttle1001 hrUser IDMutations
6Booking Burst51 minUser IDBookings

Route Mapping

RouteLimiters
/api/v1/authAuth Brute Force
/api/v1/eventsScrape → Write
/api/v1/moviesScrape → Write
/api/v1/slotsScrape → Write
/api/v1/bookingsGlobal → JWT → User → Booking
/api/v1/usersGlobal → JWT → User → Write
/api/v1/organizerGlobal → JWT → User → Write
Graceful Degradation

Redis down? Limits silently disabled (passOnStoreError: true). API stays up.

Redis Caching

Cache-aside on read endpoints. Auto-invalidation on writes. Fail-open.

60s
Default TTL
<5ms
Cache Hit
Auto
Invalidation
Fail-Open
Degradation

Flow

1GET
2Redis check
3aHIT → return
3bMISS → DB
4Store (60s)
5Return

Cached Endpoints

EndpointTTLKey
GET /api/v1/events60scache:/api/v1/events
GET /api/v1/events/:id60scache:/api/v1/events/:id
GET /api/v1/movies60scache:/api/v1/movies
GET /api/v1/movies/:id60scache:/api/v1/movies/:id

Real-Time Events

Socket.io delivers instant notifications — no polling.

Client Setup
import { io } from 'socket.io-client';
const socket = io('https://venue-z8ti.onrender.com', {
  transports: ['websocket', 'polling'], withCredentials: true
});
socket.emit('join', userId);
socket.on('waitlist:promoted', (d) => console.log('Seat!', d.bookingId));

Events

EventDirectionTriggerPayload
joinClient → ServerAfter loginuserId
waitlist:addedServer → ClientSlot full{ slotId, quantity, message }
waitlist:promotedServer → ClientSeat freed{ slotId, bookingId, quantity, message }

Waitlist Lifecycle

1Book full slot
2Auto-waitlisted
3Someone cancels
4First match promoted
5Booking auto-created

Error Handling

Structured responses. Every error includes a requestId for tracing.

Success
{ "statusCode": 200, "status": "success", "data": { ... }, "success": true }
Error
{ "status": "fail", "message": "...", "requestId": "uuid" }
StatusMeaningCauseFix
400Bad RequestValidation, invalid IDCheck body/params
401UnauthorizedMissing/expired JWTLogin again
403ForbiddenWrong roleCorrect account
404Not FoundMissing resourceVerify ID
409ConflictOverlap/duplicateDifferent slot
429Rate LimitedToo many requestsWait for reset
500Server ErrorUnhandledRetry + requestId

Troubleshooting

Cause: JWT expired or cookie not sent.
Fix: withCredentials: true. Check domain. Login again.

Fix: Register with "role": "ORGANIZER".

Check RateLimit-Reset header. Wait. Implement backoff.

Slot was full. You're FIFO queued. Listen for waitlist:promoted via Socket.io.

Security

Defense-in-depth: 8 middleware layers on every request.

🔐

Argon2id

64 MB, 3 iter, 4 threads — GPU & side-channel resistant.

🛡️

Helmet

15+ headers: CSP, HSTS, X-Frame, X-Content-Type…

🧹

XSS Sanitize

Recursive sanitize-html — strips all HTML.

💉

NoSQL Injection

mongo-sanitize strips $ and . operators.

🍪

httpOnly Cookies

Immune to XSS token theft. Secure + SameSite in prod.

📝

Log Redaction

Winston redacts password, token, auth, cookie fields.

Middleware Stack

#LayerPurpose
1HelmetSecurity headers
2Request IDUUID v4 tracing
3Morgan → WinstonStructured logging + redaction
4CORSOrigin whitelist, credentials
5JSON ParserBody parsing
6Cookie ParserhttpOnly cookies
7sanitize-htmlXSS prevention
8mongo-sanitizeNoSQL injection

Upload Limits

SettingValue
StorageCloudinary
Formatsjpg, jpeg, png, gif
Max Size5 MB
ValidationExtension regex + MIME

API Explorer

Full interactive API reference. All endpoints listed below — click "Authorize" to enter your Bearer token, then "Try it out" on any endpoint to test live.