Files
thrillwiki_django_no_react/docs/THRILLWIKI_API_DOCUMENTATION.md
pacnpal edcd8f2076 Add secret management guide, client-side performance monitoring, and search accessibility enhancements
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols.
- Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage.
- Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
2025-12-23 16:41:42 -05:00

1514 lines
41 KiB
Markdown

# ThrillWiki API Documentation v1
## Complete Frontend Developer Reference
**Base URL**: `/api/v1/`
**Authentication**: JWT Bearer tokens
**Content-Type**: `application/json`
---
## 🔑 Authentication Requirements
### JWT Authentication
Most endpoints require authentication via JWT Bearer tokens. Include the token in the `Authorization` header:
```bash
Authorization: Bearer <access_token>
```
### Token Lifetime
- **Access Token**: 15 minutes (configurable via `JWT_ACCESS_TOKEN_LIFETIME_MINUTES`)
- **Refresh Token**: 7 days (configurable via `JWT_REFRESH_TOKEN_LIFETIME_DAYS`)
### Unauthenticated Access
The following endpoints allow unauthenticated access:
- `GET /parks/` - List parks
- `GET /parks/<pk>/` - Park details
- `GET /rides/` - List rides
- `GET /rides/<pk>/` - Ride details
- `GET /parks/<pk>/photos/` - Park photos list
- `GET /rides/<pk>/photos/` - Ride photos list
- `POST /auth/login/` - User login
- `POST /auth/signup/` - User registration
- `POST /auth/password/reset/` - Password reset request
- `GET /auth/social/providers/` - Available social providers
---
## ⏱️ Rate Limiting
Rate limits are enforced per user/IP to prevent abuse:
| User Type | Limit |
|-----------|-------|
| Anonymous | 60 requests/minute |
| Authenticated | 1000 requests/hour |
### Rate Limit Headers
Responses include rate limit information in headers:
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1703347200
```
### Rate Limit Exceeded Response
```json
{
"error": "Request was throttled",
"error_code": "RATE_LIMIT_EXCEEDED",
"detail": "Expected available in 60 seconds."
}
```
---
## 📄 Pagination
List endpoints use page-based pagination:
### Query Parameters
| Parameter | Type | Default | Max | Description |
|-----------|------|---------|-----|-------------|
| `page` | int | 1 | - | Page number |
| `page_size` | int | 20 | 100 | Results per page |
### Paginated Response Format
```json
{
"count": 150,
"next": "https://api.thrillwiki.com/api/v1/parks/?page=2",
"previous": null,
"results": [...]
}
```
---
## 🔐 Authentication Endpoints (`/api/v1/auth/`)
### POST `/auth/login/` - User Login
Authenticate a user and receive JWT tokens.
**Request Body:**
```json
{
"username": "johndoe",
"password": "securepassword123"
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/login/ \
-H "Content-Type: application/json" \
-d '{"username": "johndoe", "password": "securepassword123"}'
```
**Success Response (200 OK):**
```json
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"user": {
"id": 42,
"username": "johndoe",
"email": "johndoe@example.com",
"display_name": "John Doe",
"avatar_url": "https://imagedelivery.net/xxx/avatar.jpg"
}
}
```
**Error Response (400 Bad Request):**
```json
{
"error": "Invalid credentials",
"error_code": "INVALID_CREDENTIALS",
"details": {
"non_field_errors": ["Unable to log in with provided credentials."]
}
}
```
---
### POST `/auth/signup/` - User Registration
Register a new user account. Email verification is required before full access.
**Request Body:**
```json
{
"username": "newuser",
"email": "newuser@example.com",
"password1": "ComplexPass123!",
"password2": "ComplexPass123!"
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/signup/ \
-H "Content-Type: application/json" \
-d '{"username": "newuser", "email": "newuser@example.com", "password1": "ComplexPass123!", "password2": "ComplexPass123!"}'
```
**Success Response (201 Created):**
```json
{
"success": true,
"message": "Verification email sent. Please check your inbox.",
"user": {
"id": 43,
"username": "newuser",
"email": "newuser@example.com"
}
}
```
**Error Response (400 Bad Request):**
```json
{
"error": "Validation failed",
"error_code": "VALIDATION_ERROR",
"details": {
"username": ["A user with that username already exists."],
"password1": ["This password is too common."]
}
}
```
---
### POST `/auth/logout/` - User Logout
Logout the current user and blacklist the refresh token.
**Authentication:** Required
**Request Body (optional):**
```json
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/logout/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}'
```
**Success Response (200 OK):**
```json
{
"message": "Successfully logged out."
}
```
---
### GET `/auth/user/` - Get Current User
Retrieve the authenticated user's information.
**Authentication:** Required
**curl Example:**
```bash
curl -X GET https://api.thrillwiki.com/api/v1/auth/user/ \
-H "Authorization: Bearer <access_token>"
```
**Success Response (200 OK):**
```json
{
"id": 42,
"username": "johndoe",
"email": "johndoe@example.com",
"display_name": "John Doe",
"date_joined": "2024-01-15T10:30:00Z",
"is_active": true,
"avatar_url": "https://imagedelivery.net/xxx/avatar.jpg"
}
```
---
### POST `/auth/status/` - Check Authentication Status
Check if the current request is authenticated.
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/status/ \
-H "Authorization: Bearer <access_token>"
```
**Authenticated Response (200 OK):**
```json
{
"authenticated": true,
"user": {
"id": 42,
"username": "johndoe"
}
}
```
**Unauthenticated Response (200 OK):**
```json
{
"authenticated": false
}
```
---
### POST `/auth/password/reset/` - Request Password Reset
Request a password reset email.
**Request Body:**
```json
{
"email": "johndoe@example.com"
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/password/reset/ \
-H "Content-Type: application/json" \
-d '{"email": "johndoe@example.com"}'
```
**Success Response (200 OK):**
```json
{
"message": "Password reset email sent."
}
```
> **Note:** For security, this endpoint always returns success, regardless of whether the email exists.
---
### POST `/auth/password/change/` - Change Password
Change the authenticated user's password.
**Authentication:** Required
**Request Body:**
```json
{
"old_password": "currentpassword",
"new_password1": "NewComplexPass123!",
"new_password2": "NewComplexPass123!"
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/password/change/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"old_password": "currentpassword", "new_password1": "NewComplexPass123!", "new_password2": "NewComplexPass123!"}'
```
**Success Response (200 OK):**
```json
{
"message": "Password changed successfully."
}
```
---
### POST `/auth/token/refresh/` - Refresh Access Token
Obtain a new access token using a refresh token.
**Request Body:**
```json
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/auth/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}'
```
**Success Response (200 OK):**
```json
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
```
> **Note:** Refresh tokens are rotated on each use. The old refresh token is blacklisted.
---
### GET `/auth/social/providers/` - Get Social Providers
List available social authentication providers.
**curl Example:**
```bash
curl -X GET https://api.thrillwiki.com/api/v1/auth/social/providers/
```
**Success Response (200 OK):**
```json
[
{
"provider": "google",
"name": "Google",
"enabled": true
},
{
"provider": "discord",
"name": "Discord",
"enabled": true
}
]
```
---
### Email Verification Endpoints
- **GET** `/auth/verify-email/<token>/` - Verify email with token
- **POST** `/auth/resend-verification/` - Resend email verification
### Social Authentication Endpoints
- **GET** `/auth/social/providers/available/` - Get available social providers list
- **GET** `/auth/social/connected/` - Get user's connected social providers (auth required)
- **POST** `/auth/social/connect/<provider>/` - Connect social provider (auth required)
- **POST** `/auth/social/disconnect/<provider>/` - Disconnect social provider (auth required)
- **GET** `/auth/social/status/` - Get comprehensive social auth status (auth required)
---
## 🏞️ Parks API Endpoints (`/api/v1/parks/`)
### GET `/parks/hybrid/` - List Parks with Hybrid Filtering
Retrieve parks with intelligent hybrid filtering strategy. This endpoint provides optimal performance by selecting between database and client-side filtering based on the query.
**Authentication:** Optional
**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `search` | string | Search by park name |
| `status` | string | Filter by status (OPERATING, CLOSED_PERM, UNDER_CONSTRUCTION) |
| `continent` | string | Filter by continent code |
| `country` | string | Filter by country code |
| `state` | string | Filter by state/province |
| `operator_slug` | string | Filter by operator slug |
| `rating_min` | float | Minimum rating (0-10) |
| `rating_max` | float | Maximum rating (0-10) |
| `opening_year_min` | int | Minimum opening year |
| `opening_year_max` | int | Maximum opening year |
| `coaster_count_min` | int | Minimum roller coaster count |
| `coaster_count_max` | int | Maximum roller coaster count |
| `offset` | int | Pagination offset for progressive loading |
| `ordering` | string | Sort field (name, -name, rating, -rating) |
**curl Example:**
```bash
# List operating parks in North America with rating >= 7
curl -X GET "https://api.thrillwiki.com/api/v1/parks/hybrid/?status=OPERATING&continent=NA&rating_min=7"
```
**Success Response (200 OK):**
```json
{
"success": true,
"data": {
"parks": [
{
"id": 1,
"name": "Cedar Point",
"slug": "cedar-point",
"description": "The Roller Coaster Capital of the World",
"status": "OPERATING",
"park_type": "THEME",
"opening_year": 1870,
"location": {
"continent": "NA",
"country": "US",
"state": "OH",
"city": "Sandusky",
"latitude": 41.4784,
"longitude": -82.6775
},
"operator": {
"id": 5,
"name": "Cedar Fair",
"slug": "cedar-fair"
},
"statistics": {
"ride_count": 72,
"roller_coaster_count": 17,
"average_rating": 9.2
},
"image_url": "https://imagedelivery.net/xxx/park-main.jpg"
}
],
"total_count": 45,
"has_more": true,
"strategy": "database",
"filter_metadata": {
"statuses": ["OPERATING", "CLOSED_PERM", "UNDER_CONSTRUCTION"],
"continents": ["NA", "EU", "AS", "SA", "OC", "AF"]
}
}
}
```
---
### GET `/parks/<pk>/` - Get Park Details
Retrieve detailed information about a specific park by ID or slug.
**Authentication:** Optional
**curl Example:**
```bash
curl -X GET https://api.thrillwiki.com/api/v1/parks/cedar-point/
```
**Success Response (200 OK):**
```json
{
"id": 1,
"name": "Cedar Point",
"slug": "cedar-point",
"description": "The Roller Coaster Capital of the World, featuring world-class thrill rides.",
"status": "OPERATING",
"park_type": "THEME",
"opening_year": 1870,
"website": "https://www.cedarpoint.com",
"location": {
"address": "1 Cedar Point Drive",
"city": "Sandusky",
"state": "OH",
"country": "US",
"continent": "NA",
"postal_code": "44870",
"latitude": 41.4784,
"longitude": -82.6775
},
"operator": {
"id": 5,
"name": "Cedar Fair",
"slug": "cedar-fair"
},
"property_owner": {
"id": 5,
"name": "Cedar Fair",
"slug": "cedar-fair"
},
"statistics": {
"ride_count": 72,
"roller_coaster_count": 17,
"flat_ride_count": 32,
"water_ride_count": 8,
"average_rating": 9.2,
"review_count": 1523
},
"images": {
"primary": "https://imagedelivery.net/xxx/park-main.jpg",
"gallery": [
"https://imagedelivery.net/xxx/park-1.jpg",
"https://imagedelivery.net/xxx/park-2.jpg"
]
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-12-15T14:30:00Z"
}
```
**Error Response (404 Not Found):**
```json
{
"error": "Park not found",
"error_code": "NOT_FOUND",
"details": {
"message": "No park exists with the given identifier."
}
}
```
---
### POST `/parks/` - Create Park
Create a new park entry.
**Authentication:** Required
**Request Body:**
```json
{
"name": "New Theme Park",
"description": "An exciting new theme park opening soon.",
"status": "UNDER_CONSTRUCTION",
"park_type": "THEME",
"opening_year": 2025,
"operator_id": 5,
"location": {
"city": "Orlando",
"state": "FL",
"country": "US",
"latitude": 28.3772,
"longitude": -81.5707
}
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/parks/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"name": "New Theme Park", "status": "UNDER_CONSTRUCTION", "park_type": "THEME"}'
```
**Success Response (201 Created):**
```json
{
"success": true,
"data": {
"id": 156,
"name": "New Theme Park",
"slug": "new-theme-park",
"status": "UNDER_CONSTRUCTION"
},
"message": "Park created successfully."
}
```
---
### POST `/parks/<park_pk>/photos/` - Upload Park Photo
Upload a photo for a park.
**Authentication:** Required
**Content-Type:** `multipart/form-data`
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/parks/1/photos/ \
-H "Authorization: Bearer <access_token>" \
-F "image=@/path/to/photo.jpg" \
-F "caption=Beautiful entrance view" \
-F "photo_type=GENERAL"
```
**Success Response (201 Created):**
```json
{
"id": 523,
"image_url": "https://imagedelivery.net/xxx/photo.jpg",
"caption": "Beautiful entrance view",
"photo_type": "GENERAL",
"is_primary": false,
"is_approved": false,
"uploaded_by": {
"id": 42,
"username": "johndoe"
},
"created_at": "2024-12-20T10:30:00Z"
}
```
---
### POST `/parks/<park_pk>/photos/bulk_approve/` - Bulk Approve Photos (Admin)
Bulk approve or reject multiple photos at once.
**Authentication:** Required (Staff only)
**Request Body:**
```json
{
"photo_ids": [523, 524, 525],
"approve": true
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/parks/1/photos/bulk_approve/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"photo_ids": [523, 524, 525], "approve": true}'
```
**Success Response (200 OK):**
```json
{
"success": true,
"message": "3 photos approved successfully.",
"processed": 3
}
```
**Error Response (403 Forbidden):**
```json
{
"error": "Permission denied",
"error_code": "FORBIDDEN",
"details": {
"message": "Staff privileges required for bulk operations."
}
}
```
---
### GET `/parks/filter-metadata/` - Get Filter Metadata
Retrieve available filter options and value ranges for park filtering.
**curl Example:**
```bash
curl -X GET https://api.thrillwiki.com/api/v1/parks/filter-metadata/
```
**Success Response (200 OK):**
```json
{
"success": true,
"data": {
"categorical": {
"statuses": [
{"value": "OPERATING", "label": "Operating", "count": 2500},
{"value": "CLOSED_PERM", "label": "Permanently Closed", "count": 850},
{"value": "UNDER_CONSTRUCTION", "label": "Under Construction", "count": 45}
],
"park_types": [
{"value": "THEME", "label": "Theme Park", "count": 1200},
{"value": "AMUSEMENT", "label": "Amusement Park", "count": 1800}
],
"continents": [
{"value": "NA", "label": "North America", "count": 1100},
{"value": "EU", "label": "Europe", "count": 900}
]
},
"ranges": {
"opening_year": {"min": 1843, "max": 2025},
"rating": {"min": 0, "max": 10},
"ride_count": {"min": 0, "max": 150},
"coaster_count": {"min": 0, "max": 20}
},
"total_count": 3395
}
}
```
---
### Additional Parks Endpoints
#### Search & Filtering
- **GET** `/parks/filter-options/` - Get available filter options (legacy)
- **GET** `/parks/search/companies/?q=<query>` - Search companies/operators
- **GET** `/parks/search-suggestions/?q=<query>` - Get park search suggestions
#### Park Photos
- **GET** `/parks/<park_pk>/photos/` - List park photos
- **GET** `/parks/<park_pk>/photos/<id>/` - Get park photo details
- **PATCH** `/parks/<park_pk>/photos/<id>/` - Update park photo (auth required)
- **DELETE** `/parks/<park_pk>/photos/<id>/` - Delete park photo (auth required)
- **POST** `/parks/<park_pk>/photos/<id>/set_primary/` - Set photo as primary (auth required)
- **GET** `/parks/<park_pk>/photos/stats/` - Get park photo statistics
#### Park Settings
- **GET** `/parks/<pk>/image-settings/` - Get park image settings
- **POST** `/parks/<pk>/image-settings/` - Update park image settings
---
## 🎢 Rides API Endpoints (`/api/v1/rides/`)
### GET `/rides/hybrid/` - List Rides with Hybrid Filtering
Retrieve rides with intelligent filtering. Similar to parks, this endpoint uses hybrid strategy for optimal performance.
**Authentication:** Optional
**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `search` | string | Search by ride name |
| `park` | string | Filter by park slug |
| `category` | string | Filter by category (RC, DR, FR, WR, TR, OT) |
| `manufacturer_slug` | string | Filter by manufacturer |
| `status` | string | Filter by status |
| `speed_min` | float | Minimum speed (mph) |
| `speed_max` | float | Maximum speed (mph) |
| `height_min` | float | Minimum height (ft) |
| `height_max` | float | Maximum height (ft) |
| `opening_year_min` | int | Minimum opening year |
| `opening_year_max` | int | Maximum opening year |
| `ordering` | string | Sort field |
**curl Example:**
```bash
# List roller coasters at Cedar Point
curl -X GET "https://api.thrillwiki.com/api/v1/rides/hybrid/?park=cedar-point&category=RC"
```
**Success Response (200 OK):**
```json
{
"success": true,
"data": {
"rides": [
{
"id": 42,
"name": "Steel Vengeance",
"slug": "steel-vengeance",
"category": "RC",
"category_display": "Roller Coaster",
"status": "OPERATING",
"opening_year": 2018,
"park": {
"id": 1,
"name": "Cedar Point",
"slug": "cedar-point"
},
"manufacturer": {
"id": 10,
"name": "Rocky Mountain Construction",
"slug": "rocky-mountain-construction"
},
"statistics": {
"height_ft": 205,
"speed_mph": 74,
"length_ft": 5740,
"inversions": 4,
"average_rating": 9.8
},
"image_url": "https://imagedelivery.net/xxx/ride.jpg"
}
],
"total_count": 17,
"has_more": false,
"strategy": "database"
}
}
```
---
### GET `/rides/<pk>/` - Get Ride Details
Retrieve detailed information about a specific ride.
**Authentication:** Optional
**curl Example:**
```bash
curl -X GET https://api.thrillwiki.com/api/v1/rides/steel-vengeance/
```
**Success Response (200 OK):**
```json
{
"id": 42,
"name": "Steel Vengeance",
"slug": "steel-vengeance",
"description": "A record-breaking hybrid coaster built on the bones of Mean Streak.",
"category": "RC",
"category_display": "Roller Coaster",
"status": "OPERATING",
"opening_year": 2018,
"park": {
"id": 1,
"name": "Cedar Point",
"slug": "cedar-point"
},
"manufacturer": {
"id": 10,
"name": "Rocky Mountain Construction",
"slug": "rocky-mountain-construction"
},
"ride_model": {
"id": 15,
"name": "IBox Track Conversion",
"slug": "ibox-track-conversion"
},
"specifications": {
"height_ft": 205,
"drop_ft": 200,
"speed_mph": 74,
"length_ft": 5740,
"duration_seconds": 150,
"inversions": 4,
"capacity_per_hour": 1200,
"min_height_inches": 52
},
"statistics": {
"average_rating": 9.8,
"review_count": 2847,
"ranking_position": 1
},
"images": {
"primary": "https://imagedelivery.net/xxx/ride-main.jpg",
"gallery": [
"https://imagedelivery.net/xxx/ride-1.jpg"
]
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-12-15T14:30:00Z"
}
```
---
### POST `/rides/` - Create Ride
Create a new ride entry.
**Authentication:** Required
**Request Body:**
```json
{
"name": "New Coaster",
"category": "RC",
"status": "UNDER_CONSTRUCTION",
"park_id": 1,
"manufacturer_id": 10,
"opening_year": 2025,
"specifications": {
"height_ft": 300,
"speed_mph": 90
}
}
```
**curl Example:**
```bash
curl -X POST https://api.thrillwiki.com/api/v1/rides/ \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"name": "New Coaster", "category": "RC", "park_id": 1}'
```
**Success Response (201 Created):**
```json
{
"success": true,
"data": {
"id": 1523,
"name": "New Coaster",
"slug": "new-coaster",
"category": "RC"
},
"message": "Ride created successfully."
}
```
---
### Ride Category Codes
| Code | Category |
|------|----------|
| `RC` | Roller Coaster |
| `DR` | Dark Ride |
| `FR` | Flat Ride |
| `WR` | Water Ride |
| `TR` | Transport Ride |
| `OT` | Other |
---
### Additional Rides Endpoints
#### Search & Filtering
- **GET** `/rides/filter-options/` - Get available filter options
- **GET** `/rides/search/companies/?q=<query>` - Search ride companies
- **GET** `/rides/search/ride-models/?q=<query>` - Search ride models
- **GET** `/rides/search-suggestions/?q=<query>` - Get ride search suggestions
- **GET** `/rides/hybrid/filter-metadata/` - Get ride filter metadata
#### Ride Photos
- **GET** `/rides/<ride_pk>/photos/` - List ride photos
- **POST** `/rides/<ride_pk>/photos/` - Upload ride photo (auth required)
- **GET** `/rides/<ride_pk>/photos/<id>/` - Get ride photo details
- **PATCH** `/rides/<ride_pk>/photos/<id>/` - Update ride photo (auth required)
- **DELETE** `/rides/<ride_pk>/photos/<id>/` - Delete ride photo (auth required)
- **POST** `/rides/<ride_pk>/photos/<id>/set_primary/` - Set photo as primary (auth required)
#### Ride Manufacturers
- **GET** `/rides/manufacturers/<manufacturer_slug>/` - List manufacturer's rides
#### Ride Settings
- **GET** `/rides/<pk>/image-settings/` - Get ride image settings
- **POST** `/rides/<pk>/image-settings/` - Update ride image settings
---
## 👤 User Accounts API (`/api/v1/accounts/`)
### User Management (Admin)
- **DELETE** `/accounts/users/<user_id>/delete/` - Delete user while preserving submissions
- **GET** `/accounts/users/<user_id>/deletion-check/` - Check user deletion eligibility
### Self-Service Account Management
- **POST** `/accounts/delete-account/request/` - Request account deletion
- **POST** `/accounts/delete-account/verify/` - Verify account deletion
- **POST** `/accounts/delete-account/cancel/` - Cancel account deletion
### User Profile Management
- **GET** `/accounts/profile/` - Get user profile
- **PATCH** `/accounts/profile/account/` - Update user account info
- **PATCH** `/accounts/profile/update/` - Update user profile
### User Preferences
- **GET** `/accounts/preferences/` - Get user preferences
- **PATCH** `/accounts/preferences/update/` - Update user preferences
- **PATCH** `/accounts/preferences/theme/` - Update theme preference
### Settings Management
- **GET** `/accounts/settings/notifications/` - Get notification settings
- **PATCH** `/accounts/settings/notifications/update/` - Update notification settings
- **GET** `/accounts/settings/privacy/` - Get privacy settings
- **PATCH** `/accounts/settings/privacy/update/` - Update privacy settings
- **GET** `/accounts/settings/security/` - Get security settings
- **PATCH** `/accounts/settings/security/update/` - Update security settings
### User Statistics & Lists
- **GET** `/accounts/statistics/` - Get user statistics
- **GET** `/accounts/top-lists/` - Get user's top lists
- **POST** `/accounts/top-lists/create/` - Create new top list
- **PATCH** `/accounts/top-lists/<list_id>/` - Update top list
- **DELETE** `/accounts/top-lists/<list_id>/delete/` - Delete top list
### Notifications
- **GET** `/accounts/notifications/` - Get user notifications
- **POST** `/accounts/notifications/mark-read/` - Mark notifications as read
- **GET** `/accounts/notification-preferences/` - Get notification preferences
- **PATCH** `/accounts/notification-preferences/update/` - Update notification preferences
### Avatar Management
- **POST** `/accounts/profile/avatar/upload/` - Upload avatar
- **POST** `/accounts/profile/avatar/save/` - Save avatar image
- **DELETE** `/accounts/profile/avatar/delete/` - Delete avatar
---
## 🗺️ Maps API (`/api/v1/maps/`)
### Location Data
- **GET** `/maps/locations/` - Get map locations data
- **GET** `/maps/locations/<location_type>/<location_id>/` - Get location details
- **GET** `/maps/search/` - Search locations on map
- **GET** `/maps/bounds/` - Query locations within bounds
### Map Services
- **GET** `/maps/stats/` - Get map service statistics
- **GET** `/maps/cache/` - Get map cache information
- **POST** `/maps/cache/invalidate/` - Invalidate map cache
---
## 🔍 Core Search API (`/api/v1/core/`)
### Entity Search
- **GET** `/core/entities/search/` - Fuzzy search for entities
- **GET** `/core/entities/not-found/` - Handle entity not found
- **GET** `/core/entities/suggestions/` - Quick entity suggestions
---
## 📧 Email API (`/api/v1/email/`)
### Email Services
- **POST** `/email/send/` - Send email
---
## 📜 History API (`/api/v1/history/`)
### Park History
- **GET** `/history/parks/<park_slug>/` - Get park history
- **GET** `/history/parks/<park_slug>/detail/` - Get detailed park history
### Ride History
- **GET** `/history/parks/<park_slug>/rides/<ride_slug>/` - Get ride history
- **GET** `/history/parks/<park_slug>/rides/<ride_slug>/detail/` - Get detailed ride history
### Unified Timeline
- **GET** `/history/timeline/` - Get unified history timeline
---
## 📈 System & Analytics APIs
### Health Checks
- **GET** `/api/v1/health/` - Comprehensive health check
- **GET** `/api/v1/health/simple/` - Simple health check
- **GET** `/api/v1/health/performance/` - Performance metrics
### Trending & Discovery
- **GET** `/api/v1/trending/` - Get trending content
- **GET** `/api/v1/new-content/` - Get new content
- **POST** `/api/v1/trending/calculate/` - Trigger trending calculation
### Statistics
- **GET** `/api/v1/stats/` - Get system statistics
- **POST** `/api/v1/stats/recalculate/` - Recalculate statistics
### Reviews
- **GET** `/api/v1/reviews/latest/` - Get latest reviews
### Rankings
- **GET** `/api/v1/rankings/` - Get ride rankings with filtering
- **GET** `/api/v1/rankings/<ride_slug>/` - Get detailed ranking for specific ride
- **GET** `/api/v1/rankings/<ride_slug>/history/` - Get ranking history for ride
- **GET** `/api/v1/rankings/<ride_slug>/comparisons/` - Get head-to-head comparisons
- **GET** `/api/v1/rankings/statistics/` - Get ranking system statistics
- **POST** `/api/v1/rankings/calculate/` - Trigger ranking calculation (admin)
#### Rankings Filtering Parameters:
- **category**: Filter by ride category (RC, DR, FR, WR, TR, OT)
- **min_riders**: Minimum number of mutual riders required
- **park**: Filter by park slug
- **ordering**: Order results (rank, -rank, winning_percentage, -winning_percentage)
---
## 🛡️ Moderation API (`/api/v1/moderation/`)
### Moderation Reports
- **GET** `/moderation/reports/` - List all moderation reports
- **POST** `/moderation/reports/` - Create new moderation report
- **GET** `/moderation/reports/<id>/` - Get specific report details
- **PUT** `/moderation/reports/<id>/` - Update moderation report
- **PATCH** `/moderation/reports/<id>/` - Partial update report
- **DELETE** `/moderation/reports/<id>/` - Delete moderation report
- **POST** `/moderation/reports/<id>/assign/` - Assign report to moderator
- **POST** `/moderation/reports/<id>/resolve/` - Resolve moderation report
- **GET** `/moderation/reports/stats/` - Get report statistics
### Moderation Queue
- **GET** `/moderation/queue/` - List moderation queue items
- **POST** `/moderation/queue/` - Create queue item
- **GET** `/moderation/queue/<id>/` - Get specific queue item
- **PUT** `/moderation/queue/<id>/` - Update queue item
- **PATCH** `/moderation/queue/<id>/` - Partial update queue item
- **DELETE** `/moderation/queue/<id>/` - Delete queue item
- **POST** `/moderation/queue/<id>/assign/` - Assign queue item to moderator
- **POST** `/moderation/queue/<id>/unassign/` - Unassign queue item
- **POST** `/moderation/queue/<id>/complete/` - Complete queue item
- **GET** `/moderation/queue/my_queue/` - Get current user's queue items
### Moderation Actions
- **GET** `/moderation/actions/` - List all moderation actions
- **POST** `/moderation/actions/` - Create new moderation action
- **GET** `/moderation/actions/<id>/` - Get specific action details
- **PUT** `/moderation/actions/<id>/` - Update moderation action
- **PATCH** `/moderation/actions/<id>/` - Partial update action
- **DELETE** `/moderation/actions/<id>/` - Delete moderation action
- **POST** `/moderation/actions/<id>/deactivate/` - Deactivate action
- **GET** `/moderation/actions/active/` - Get active moderation actions
- **GET** `/moderation/actions/expired/` - Get expired moderation actions
### Bulk Operations
- **GET** `/moderation/bulk-operations/` - List bulk moderation operations
- **POST** `/moderation/bulk-operations/` - Create bulk operation
- **GET** `/moderation/bulk-operations/<id>/` - Get bulk operation details
- **PUT** `/moderation/bulk-operations/<id>/` - Update bulk operation
- **PATCH** `/moderation/bulk-operations/<id>/` - Partial update operation
- **DELETE** `/moderation/bulk-operations/<id>/` - Delete bulk operation
- **POST** `/moderation/bulk-operations/<id>/cancel/` - Cancel bulk operation
- **POST** `/moderation/bulk-operations/<id>/retry/` - Retry failed operation
- **GET** `/moderation/bulk-operations/<id>/logs/` - Get operation logs
- **GET** `/moderation/bulk-operations/running/` - Get running operations
### User Moderation
- **GET** `/moderation/users/<id>/` - Get user moderation profile
- **POST** `/moderation/users/<id>/moderate/` - Take moderation action against user
- **GET** `/moderation/users/search/` - Search users for moderation
- **GET** `/moderation/users/stats/` - Get user moderation statistics
---
## 🏗️ Ride Manufacturers & Models (`/api/v1/rides/manufacturers/<manufacturer_slug>/`)
### Ride Models
- **GET** `/rides/manufacturers/<manufacturer_slug>/` - List ride models by manufacturer
- **POST** `/rides/manufacturers/<manufacturer_slug>/` - Create new ride model
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Get ride model details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Update ride model
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/` - Delete ride model
### Model Search & Filtering
- **GET** `/rides/manufacturers/<manufacturer_slug>/search/` - Search ride models
- **GET** `/rides/manufacturers/<manufacturer_slug>/filter-options/` - Get filter options
- **GET** `/rides/manufacturers/<manufacturer_slug>/stats/` - Get manufacturer statistics
### Model Variants
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/` - List model variants
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/` - Create variant
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Get variant details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Update variant
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/variants/<id>/` - Delete variant
### Technical Specifications
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/` - List technical specs
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/` - Create technical spec
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Get spec details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Update spec
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/technical-specs/<id>/` - Delete spec
### Model Photos
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/` - List model photos
- **POST** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/` - Upload model photo
- **GET** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Get photo details
- **PATCH** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Update photo
- **DELETE** `/rides/manufacturers/<manufacturer_slug>/<ride_model_slug>/photos/<id>/` - Delete photo
---
## 🖼️ Media Management
### Cloudflare Images
- **ALL** `/api/v1/cloudflare-images/` - Cloudflare Images toolkit endpoints
---
## 📚 API Documentation
### Interactive Documentation
- **GET** `/api/schema/` - OpenAPI schema
- **GET** `/api/docs/` - Swagger UI documentation
- **GET** `/api/redoc/` - ReDoc documentation
---
## 🔧 Common Request/Response Patterns
### Authentication Headers
```javascript
headers: {
'Authorization': 'Bearer <access_token>',
'Content-Type': 'application/json'
}
```
### Pagination Response
```json
{
"count": 100,
"next": "https://api.thrillwiki.com/api/v1/endpoint/?page=2",
"previous": null,
"results": [...]
}
```
### Success Response Format
```json
{
"success": true,
"message": "Operation completed successfully",
"data": {...}
}
```
---
## ❌ Error Response Reference
All error responses follow a consistent format with appropriate HTTP status codes.
### Error Response Structure
```json
{
"error": "Human-readable error message",
"error_code": "MACHINE_READABLE_CODE",
"details": {
"field_name": ["Specific field error message"]
},
"suggestions": ["Suggestion for resolution"]
}
```
### HTTP Status Codes
| Code | Meaning | When Used |
|------|---------|-----------|
| 400 | Bad Request | Invalid request body, missing required fields, validation errors |
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Authenticated but lacks permission for the action |
| 404 | Not Found | Requested resource doesn't exist |
| 405 | Method Not Allowed | HTTP method not supported for endpoint |
| 409 | Conflict | Resource conflict (e.g., duplicate entry) |
| 422 | Unprocessable Entity | Request understood but semantically incorrect |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
### Common Error Codes
#### Authentication Errors (401)
```json
{
"error": "Authentication credentials were not provided",
"error_code": "AUTHENTICATION_REQUIRED"
}
```
```json
{
"error": "Token is invalid or expired",
"error_code": "INVALID_TOKEN",
"details": {
"token_type": "access",
"message": "Token has expired"
}
}
```
#### Authorization Errors (403)
```json
{
"error": "Permission denied",
"error_code": "FORBIDDEN",
"details": {
"message": "You do not have permission to perform this action.",
"required_permission": "is_staff"
}
}
```
#### Validation Errors (400)
```json
{
"error": "Validation failed",
"error_code": "VALIDATION_ERROR",
"details": {
"name": ["This field is required."],
"email": ["Enter a valid email address."],
"password1": [
"This password is too short. It must contain at least 8 characters.",
"This password is too common."
]
}
}
```
#### Not Found Errors (404)
```json
{
"error": "Park not found",
"error_code": "NOT_FOUND",
"details": {
"resource": "Park",
"identifier": "nonexistent-park-slug"
}
}
```
#### Rate Limit Errors (429)
```json
{
"error": "Request was throttled",
"error_code": "RATE_LIMIT_EXCEEDED",
"detail": "Expected available in 45 seconds.",
"retry_after": 45
}
```
#### Conflict Errors (409)
```json
{
"error": "Resource already exists",
"error_code": "DUPLICATE_ENTRY",
"details": {
"field": "username",
"message": "A user with this username already exists."
}
}
```
---
## 📝 Key Data Models
### User
| Field | Type | Description |
|-------|------|-------------|
| `id` | int | Unique identifier |
| `username` | string | Unique username |
| `email` | string | Email address |
| `display_name` | string | Display name |
| `date_joined` | datetime | Account creation date |
| `is_active` | boolean | Account active status |
| `avatar_url` | string | Avatar image URL |
### Park
| Field | Type | Description |
|-------|------|-------------|
| `id` | int | Unique identifier |
| `name` | string | Park name |
| `slug` | string | URL-friendly identifier |
| `description` | string | Park description |
| `status` | enum | OPERATING, CLOSED_PERM, UNDER_CONSTRUCTION |
| `park_type` | enum | THEME, AMUSEMENT, WATER, etc. |
| `opening_year` | int | Year park opened |
| `location` | object | Location details (city, country, coordinates) |
| `operator` | object | Operating company |
### Ride
| Field | Type | Description |
|-------|------|-------------|
| `id` | int | Unique identifier |
| `name` | string | Ride name |
| `slug` | string | URL-friendly identifier |
| `category` | enum | RC, DR, FR, WR, TR, OT |
| `status` | enum | OPERATING, CLOSED_PERM, etc. |
| `park` | object | Parent park |
| `manufacturer` | object | Ride manufacturer |
| `opening_year` | int | Year ride opened |
| `specifications` | object | Height, speed, length, etc. |
### Photo
| Field | Type | Description |
|-------|------|-------------|
| `id` | int | Unique identifier |
| `image_url` | string | Full image URL |
| `caption` | string | Photo caption |
| `photo_type` | enum | GENERAL, ENTRANCE, RIDE, etc. |
| `is_primary` | boolean | Primary photo flag |
| `is_approved` | boolean | Moderation approval status |
| `uploaded_by` | object | User who uploaded |
| `created_at` | datetime | Upload timestamp |
---
## 📖 Complete curl Examples
### Full Authentication Flow
```bash
# 1. Register a new account
curl -X POST https://api.thrillwiki.com/api/v1/auth/signup/ \
-H "Content-Type: application/json" \
-d '{
"username": "coasterenthusiast",
"email": "coaster@example.com",
"password1": "MySecurePass123!",
"password2": "MySecurePass123!"
}'
# 2. Login to get tokens
curl -X POST https://api.thrillwiki.com/api/v1/auth/login/ \
-H "Content-Type: application/json" \
-d '{"username": "coasterenthusiast", "password": "MySecurePass123!"}' \
| jq -r '.access' > access_token.txt
# 3. Use the access token for authenticated requests
ACCESS_TOKEN=$(cat access_token.txt)
curl -X GET https://api.thrillwiki.com/api/v1/auth/user/ \
-H "Authorization: Bearer $ACCESS_TOKEN"
# 4. Refresh the token when it expires
curl -X POST https://api.thrillwiki.com/api/v1/auth/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}'
# 5. Logout
curl -X POST https://api.thrillwiki.com/api/v1/auth/logout/ \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"refresh": "<refresh_token>"}'
```
### Listing and Filtering Parks
```bash
# List all operating parks
curl -X GET "https://api.thrillwiki.com/api/v1/parks/hybrid/?status=OPERATING"
# Search for parks by name
curl -X GET "https://api.thrillwiki.com/api/v1/parks/hybrid/?search=disney"
# Filter by location and rating
curl -X GET "https://api.thrillwiki.com/api/v1/parks/hybrid/?continent=NA&country=US&rating_min=8"
# Paginate through results
curl -X GET "https://api.thrillwiki.com/api/v1/parks/hybrid/?offset=20"
# Get detailed park information
curl -X GET "https://api.thrillwiki.com/api/v1/parks/cedar-point/"
```
### Working with Rides
```bash
# List all roller coasters at a specific park
curl -X GET "https://api.thrillwiki.com/api/v1/rides/hybrid/?park=cedar-point&category=RC"
# Filter by speed and height
curl -X GET "https://api.thrillwiki.com/api/v1/rides/hybrid/?speed_min=70&height_min=200"
# Get ride details
curl -X GET "https://api.thrillwiki.com/api/v1/rides/steel-vengeance/"
```
### Uploading Photos
```bash
# Upload a park photo
curl -X POST "https://api.thrillwiki.com/api/v1/parks/1/photos/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "image=@/path/to/photo.jpg" \
-F "caption=Amazing entrance view" \
-F "photo_type=ENTRANCE"
# Upload a ride photo
curl -X POST "https://api.thrillwiki.com/api/v1/rides/42/photos/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "image=@/path/to/coaster.jpg" \
-F "caption=First drop" \
-F "photo_type=GENERAL"
```
---
## 🚨 Important Notes
1. **Authentication Required**: Most write operations require JWT authentication
2. **Permissions**: Admin endpoints require staff/superuser privileges
3. **Rate Limiting**: 60 requests/minute for anonymous, 1000 requests/hour for authenticated users
4. **File Uploads**: Use `multipart/form-data` for photo uploads (max 10MB)
5. **Pagination**: Default page size is 20, maximum is 100
6. **Filtering**: Parks and rides support extensive filtering with range parameters
7. **Cloudflare Images**: All media files are served through Cloudflare Images CDN
8. **Email Verification**: New users must verify email before full access
9. **Token Rotation**: Refresh tokens are rotated on each use for security
---
This documentation covers all available API endpoints in the ThrillWiki v1 API. For detailed request/response schemas, parameter validation, and interactive testing, visit `/api/docs/` when the development server is running.