# 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 ``` ### 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//` - Park details - `GET /rides/` - List rides - `GET /rides//` - Ride details - `GET /parks//photos/` - Park photos list - `GET /rides//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 " \ -H "Content-Type: application/json" \ -d '{"refresh": ""}' ``` **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 " ``` **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 " ``` **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 " \ -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": ""}' ``` **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//` - 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//` - Connect social provider (auth required) - **POST** `/auth/social/disconnect//` - 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//` - 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 " \ -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//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 " \ -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//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 " \ -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=` - Search companies/operators - **GET** `/parks/search-suggestions/?q=` - Get park search suggestions #### Park Photos - **GET** `/parks//photos/` - List park photos - **GET** `/parks//photos//` - Get park photo details - **PATCH** `/parks//photos//` - Update park photo (auth required) - **DELETE** `/parks//photos//` - Delete park photo (auth required) - **POST** `/parks//photos//set_primary/` - Set photo as primary (auth required) - **GET** `/parks//photos/stats/` - Get park photo statistics #### Park Settings - **GET** `/parks//image-settings/` - Get park image settings - **POST** `/parks//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//` - 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 " \ -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=` - Search ride companies - **GET** `/rides/search/ride-models/?q=` - Search ride models - **GET** `/rides/search-suggestions/?q=` - Get ride search suggestions - **GET** `/rides/hybrid/filter-metadata/` - Get ride filter metadata #### Ride Photos - **GET** `/rides//photos/` - List ride photos - **POST** `/rides//photos/` - Upload ride photo (auth required) - **GET** `/rides//photos//` - Get ride photo details - **PATCH** `/rides//photos//` - Update ride photo (auth required) - **DELETE** `/rides//photos//` - Delete ride photo (auth required) - **POST** `/rides//photos//set_primary/` - Set photo as primary (auth required) #### Ride Manufacturers - **GET** `/rides/manufacturers//` - List manufacturer's rides #### Ride Settings - **GET** `/rides//image-settings/` - Get ride image settings - **POST** `/rides//image-settings/` - Update ride image settings --- ## πŸ‘€ User Accounts API (`/api/v1/accounts/`) ### User Management (Admin) - **DELETE** `/accounts/users//delete/` - Delete user while preserving submissions - **GET** `/accounts/users//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//` - Update top list - **DELETE** `/accounts/top-lists//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///` - 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//` - Get park history - **GET** `/history/parks//detail/` - Get detailed park history ### Ride History - **GET** `/history/parks//rides//` - Get ride history - **GET** `/history/parks//rides//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//` - Get detailed ranking for specific ride - **GET** `/api/v1/rankings//history/` - Get ranking history for ride - **GET** `/api/v1/rankings//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//` - Get specific report details - **PUT** `/moderation/reports//` - Update moderation report - **PATCH** `/moderation/reports//` - Partial update report - **DELETE** `/moderation/reports//` - Delete moderation report - **POST** `/moderation/reports//assign/` - Assign report to moderator - **POST** `/moderation/reports//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//` - Get specific queue item - **PUT** `/moderation/queue//` - Update queue item - **PATCH** `/moderation/queue//` - Partial update queue item - **DELETE** `/moderation/queue//` - Delete queue item - **POST** `/moderation/queue//assign/` - Assign queue item to moderator - **POST** `/moderation/queue//unassign/` - Unassign queue item - **POST** `/moderation/queue//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//` - Get specific action details - **PUT** `/moderation/actions//` - Update moderation action - **PATCH** `/moderation/actions//` - Partial update action - **DELETE** `/moderation/actions//` - Delete moderation action - **POST** `/moderation/actions//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//` - Get bulk operation details - **PUT** `/moderation/bulk-operations//` - Update bulk operation - **PATCH** `/moderation/bulk-operations//` - Partial update operation - **DELETE** `/moderation/bulk-operations//` - Delete bulk operation - **POST** `/moderation/bulk-operations//cancel/` - Cancel bulk operation - **POST** `/moderation/bulk-operations//retry/` - Retry failed operation - **GET** `/moderation/bulk-operations//logs/` - Get operation logs - **GET** `/moderation/bulk-operations/running/` - Get running operations ### User Moderation - **GET** `/moderation/users//` - Get user moderation profile - **POST** `/moderation/users//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//`) ### Ride Models - **GET** `/rides/manufacturers//` - List ride models by manufacturer - **POST** `/rides/manufacturers//` - Create new ride model - **GET** `/rides/manufacturers///` - Get ride model details - **PATCH** `/rides/manufacturers///` - Update ride model - **DELETE** `/rides/manufacturers///` - Delete ride model ### Model Search & Filtering - **GET** `/rides/manufacturers//search/` - Search ride models - **GET** `/rides/manufacturers//filter-options/` - Get filter options - **GET** `/rides/manufacturers//stats/` - Get manufacturer statistics ### Model Variants - **GET** `/rides/manufacturers///variants/` - List model variants - **POST** `/rides/manufacturers///variants/` - Create variant - **GET** `/rides/manufacturers///variants//` - Get variant details - **PATCH** `/rides/manufacturers///variants//` - Update variant - **DELETE** `/rides/manufacturers///variants//` - Delete variant ### Technical Specifications - **GET** `/rides/manufacturers///technical-specs/` - List technical specs - **POST** `/rides/manufacturers///technical-specs/` - Create technical spec - **GET** `/rides/manufacturers///technical-specs//` - Get spec details - **PATCH** `/rides/manufacturers///technical-specs//` - Update spec - **DELETE** `/rides/manufacturers///technical-specs//` - Delete spec ### Model Photos - **GET** `/rides/manufacturers///photos/` - List model photos - **POST** `/rides/manufacturers///photos/` - Upload model photo - **GET** `/rides/manufacturers///photos//` - Get photo details - **PATCH** `/rides/manufacturers///photos//` - Update photo - **DELETE** `/rides/manufacturers///photos//` - 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 ', '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": ""}' # 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": ""}' ``` ### 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.