The EventHub API provides endpoints for managing and retrieving event data for the Estonian market. The API is built with NestJS and follows RESTful conventions.
Base URL: http://localhost:3001/api
Interactive Documentation: Visit http://localhost:3001/api for Swagger UI
No authentication is required for any endpoints in the current version.
Retrieves a list of all events with their associated ticket types.
Endpoint: GET /events
Response (200 OK):
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Summer Music Festival 2026",
"description": "Three days of concerts across multiple venues in Tallinn's creative district",
"imageUrl": "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800&q=80",
"createdAt": "2025-12-22T10:00:00.000Z",
"ticketTypes": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "General Admission",
"price": "25.00",
"eventId": "550e8400-e29b-41d4-a716-446655440000"
},
{
"id": "660e8400-e29b-41d4-a716-446655440002",
"name": "VIP",
"price": "75.00",
"eventId": "550e8400-e29b-41d4-a716-446655440000"
}
]
}
]PowerShell Example:
Invoke-WebRequest -Uri "http://localhost:3001/api/events" -UseBasicParsing | Select-Object -ExpandProperty ContentcURL Example (Linux/macOS):
curl http://localhost:3001/api/eventsRetrieves a specific event by its ID.
Endpoint: GET /events/:id
Parameters:
id(string, required) - UUID of the event
Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Summer Music Festival 2026",
"description": "Three days of concerts across multiple venues in Tallinn's creative district",
"imageUrl": "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800&q=80",
"createdAt": "2025-12-22T10:00:00.000Z",
"ticketTypes": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "General Admission",
"price": "25.00",
"eventId": "550e8400-e29b-41d4-a716-446655440000"
},
{
"id": "660e8400-e29b-41d4-a716-446655440002",
"name": "VIP",
"price": "75.00",
"eventId": "550e8400-e29b-41d4-a716-446655440000"
}
]
}Error Response (404 Not Found):
{
"statusCode": 404,
"message": "Event not found"
}PowerShell Example:
Invoke-WebRequest -Uri "http://localhost:3001/api/events/550e8400-e29b-41d4-a716-446655440000" -UseBasicParsing | Select-Object -ExpandProperty ContentcURL Example (Linux/macOS):
curl http://localhost:3001/api/events/550e8400-e29b-41d4-a716-446655440000Creates a new event with associated ticket types.
Endpoint: POST /events
Headers:
Content-Type: application/json
Request Body:
{
"title": "Summer Music Festival",
"imageUrl": "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800",
"description": "Three days of concerts featuring international and local artists",
"ticketTypes": [
{
"name": "General Admission",
"price": 25.00
},
{
"name": "VIP",
"price": 75.00
}
]
}Validation Rules:
title(string, required) - Event title, must not be emptyimageUrl(string, required) - Valid HTTPS URLdescription(string, required) - Event description, must not be emptyticketTypes(array, required) - At least one ticket typename(string, required) - Ticket type nameprice(number, required) - Price must be >= 0
Response (201 Created):
{
"id": "770e8400-e29b-41d4-a716-446655440003",
"title": "Summer Music Festival",
"description": "Three days of concerts featuring international and local artists",
"imageUrl": "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800",
"createdAt": "2025-12-23T14:30:00.000Z",
"ticketTypes": [
{
"id": "880e8400-e29b-41d4-a716-446655440004",
"name": "General Admission",
"price": "25.00",
"eventId": "770e8400-e29b-41d4-a716-446655440003"
},
{
"id": "880e8400-e29b-41d4-a716-446655440005",
"name": "VIP",
"price": "75.00",
"eventId": "770e8400-e29b-41d4-a716-446655440003"
}
]
}Error Response (400 Bad Request):
{
"statusCode": 400,
"message": [
"price must not be less than 0",
"title should not be empty"
],
"error": "Bad Request"
}PowerShell Example:
$body = @{
title = "Summer Music Festival"
imageUrl = "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800"
description = "Three days of concerts featuring international and local artists"
ticketTypes = @(
@{ name = "General Admission"; price = 25.00 },
@{ name = "VIP"; price = 75.00 }
)
} | ConvertTo-Json
Invoke-WebRequest -Uri "http://localhost:3001/api/events" -Method POST -ContentType "application/json" -Body $bodycURL Example (Linux/macOS):
curl -X POST http://localhost:3001/api/events \
-H "Content-Type: application/json" \
-d '{
"title": "Summer Music Festival",
"imageUrl": "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800",
"description": "Three days of concerts featuring international and local artists",
"ticketTypes": [
{"name": "General Admission", "price": 25.00},
{"name": "VIP", "price": 75.00}
]
}'| Code | Description |
|---|---|
| 200 | OK - Request succeeded |
| 201 | Created - Resource successfully created |
| 400 | Bad Request - Invalid input or validation error |
| 404 | Not Found - Resource does not exist |
| 500 | Internal Server Error - Server-side error |
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Unique identifier |
| title | string | Event title |
| description | string | Event description |
| imageUrl | string | Valid HTTPS URL |
| createdAt | string (ISO 8601) | Creation timestamp |
| ticketTypes | TicketType[] | Associated ticket types |
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Unique identifier |
| name | string | Ticket type name (e.g., "VIP", "General Admission") |
| price | string (Decimal) | Price in EUR, formatted as string |
| eventId | string (UUID) | Associated event ID |
Rate limiting is implemented using @nestjs/throttler with the following default configuration:
- 100 requests per minute per IP address
- Time window: 60 seconds
If rate limit is exceeded, the API returns a 429 Too Many Requests response.
Configuration can be adjusted in backend/src/app.module.ts.
CORS is configured via the CORS_ORIGIN environment variable, which defaults to http://localhost:3000 for local development.
For production deployment, set the CORS_ORIGIN environment variable:
CORS_ORIGIN=https://your-production-frontend.comThe configuration is in backend/src/main.ts:
app.enableCors({
origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
credentials: true,
});Security headers are implemented using helmet middleware, including:
- Content Security Policy (CSP)
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security
Configuration can be adjusted in backend/src/main.ts.
Current version: 1.0
No API versioning is currently implemented. All endpoints are under /api.