Skip to content

API Reference

Siyâvash edited this page Dec 16, 2025 · 1 revision

API Reference

This page documents the REST API endpoints available in ExpoScholar. The API provides JSON endpoints for the Flutter mobile client and follows RESTful principles using Django REST Framework.

Base Information

Base URL: http://localhost:8000/api/v1/ (development)
Production URL: https://yourdomain.com/api/v1/
API Version: v1
Content Type: application/json (except for multipart form data endpoints)

Authentication

The API uses JWT (JSON Web Token) authentication for secure access. Most endpoints require authentication via the Authorization header.

Obtaining Tokens

POST /api/v1/token/

Obtain access and refresh tokens by providing user credentials.

Request Body:

{
  "email": "user@example.com",
  "password": "your-password"
}

Response:

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Status Codes:

  • 200 OK: Authentication successful
  • 401 Unauthorized: Invalid credentials

Refreshing Tokens

POST /api/v1/token/refresh/

Refresh an expired access token using a valid refresh token.

Request Body:

{
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Response:

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Status Codes:

  • 200 OK: Token refreshed successfully
  • 401 Unauthorized: Invalid or expired refresh token

Using Tokens

Include the access token in the Authorization header for authenticated requests:

Authorization: Bearer <access_token>

Access tokens expire after a configured period (typically 15 minutes). Use the refresh token to obtain a new access token when it expires.

Health Check

GET /api/v1/health/

Lightweight endpoint to verify server connectivity and health status.

Authentication: Not required

Response:

{
  "status": "ok"
}

Status Codes:

  • 200 OK: Server is healthy

Country Endpoints

List Countries

GET /api/v1/countries/

Retrieve a list of all available countries for dropdown selection.

Authentication: Required

Response:

[
  {
    "id": 1,
    "name": "United States",
    "code": "US"
  },
  {
    "id": 2,
    "name": "Canada",
    "code": "CA"
  }
]

Status Codes:

  • 200 OK: Countries retrieved successfully
  • 401 Unauthorized: Authentication required

Booth Endpoints

Create Booth

POST /api/v1/booths/

Create a new booth for the authenticated user.

Authentication: Required

Request: Multipart form data with the following fields:

  • name (string, required): Booth name
  • description (string, optional): Booth description
  • category (string, optional): Booth category
  • country (integer, required): Country ID
  • images (file[], optional): Booth images
  • videos (file[], optional): Booth videos

Response:

{
  "id": 1,
  "name": "My Exhibition Booth",
  "description": "Description of the booth",
  "category": "Technology",
  "country": 1,
  "images": [
    {
      "id": 1,
      "url": "https://example.com/media/booths/1/image1.jpg",
      "is_primary": true
    }
  ],
  "videos": [],
  "created_at": "2025-01-25T10:00:00Z",
  "updated_at": "2025-01-25T10:00:00Z"
}

Status Codes:

  • 201 Created: Booth created successfully
  • 400 Bad Request: Invalid input data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Subscription quota exceeded

Quota Check: The endpoint verifies that the user has not exceeded their subscription booth limit before creating a new booth.

Update Booth

PUT /api/v1/booths/<booth_pk>/

Update an existing booth. Only the booth owner can update their booths.

Authentication: Required

Request: Multipart form data with updated fields (same as create endpoint)

Response:

{
  "id": 1,
  "name": "Updated Booth Name",
  "description": "Updated description",
  "category": "Technology",
  "country": 1,
  "images": [...],
  "videos": [...],
  "created_at": "2025-01-25T10:00:00Z",
  "updated_at": "2025-01-25T11:00:00Z"
}

Status Codes:

  • 200 OK: Booth updated successfully
  • 400 Bad Request: Invalid input data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to update this booth
  • 404 Not Found: Booth not found

List Booths

GET /api/v1/booths/list/

Retrieve all booths for the authenticated user.

Authentication: Required

Response:

[
  {
    "id": 1,
    "name": "My Exhibition Booth",
    "description": "Description",
    "category": "Technology",
    "country": 1,
    "images": [...],
    "videos": [...],
    "created_at": "2025-01-25T10:00:00Z",
    "updated_at": "2025-01-25T10:00:00Z"
  }
]

Status Codes:

  • 200 OK: Booths retrieved successfully
  • 401 Unauthorized: Authentication required

Item Endpoints

Create Item

POST /api/v1/booths/<booth_pk>/items/

Create a new item within a specific booth.

Authentication: Required

Request: Multipart form data with the following fields:

  • name (string, required): Item name
  • description (string, optional): Item description
  • price (decimal, optional): Item price
  • quantity (integer, optional): Item quantity
  • images (file[], optional): Item images

Response:

{
  "id": 1,
  "name": "Exhibition Item",
  "description": "Item description",
  "price": "99.99",
  "quantity": 10,
  "booth": 1,
  "images": [
    {
      "id": 1,
      "url": "https://example.com/media/items/1/image1.jpg",
      "is_primary": true
    }
  ],
  "created_at": "2025-01-25T10:00:00Z",
  "updated_at": "2025-01-25T10:00:00Z"
}

Status Codes:

  • 201 Created: Item created successfully
  • 400 Bad Request: Invalid input data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to create items in this booth
  • 404 Not Found: Booth not found

Update Item

PUT /api/v1/booths/<booth_pk>/items/<item_pk>/

Update an existing item. Only the booth owner can update items in their booths.

Authentication: Required

Request: Multipart form data with updated fields (same as create endpoint)

Response:

{
  "id": 1,
  "name": "Updated Item Name",
  "description": "Updated description",
  "price": "149.99",
  "quantity": 5,
  "booth": 1,
  "images": [...],
  "created_at": "2025-01-25T10:00:00Z",
  "updated_at": "2025-01-25T11:00:00Z"
}

Status Codes:

  • 200 OK: Item updated successfully
  • 400 Bad Request: Invalid input data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to update this item
  • 404 Not Found: Item or booth not found

List Items

GET /api/v1/booths/<booth_pk>/items/list/

Retrieve all items for a specific booth.

Authentication: Required

Response:

[
  {
    "id": 1,
    "name": "Exhibition Item",
    "description": "Item description",
    "price": "99.99",
    "quantity": 10,
    "booth": 1,
    "images": [...],
    "created_at": "2025-01-25T10:00:00Z",
    "updated_at": "2025-01-25T10:00:00Z"
  }
]

Status Codes:

  • 200 OK: Items retrieved successfully
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Booth not found

Media Endpoints

Booth Images

Create Booth Image

POST /api/v1/booths/<booth_pk>/images/

Upload an image for a specific booth.

Authentication: Required

Request: Multipart form data:

  • image (file, required): Image file

Response:

{
  "id": 1,
  "url": "https://example.com/media/booths/1/image1.jpg",
  "is_primary": false,
  "booth": 1
}

Status Codes:

  • 201 Created: Image uploaded successfully
  • 400 Bad Request: Invalid file or data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to upload images for this booth
  • 404 Not Found: Booth not found

Delete Booth Image

DELETE /api/v1/booths/<booth_pk>/images/<image_pk>/

Delete a specific booth image.

Authentication: Required

Status Codes:

  • 204 No Content: Image deleted successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to delete this image
  • 404 Not Found: Image or booth not found

Set Primary Booth Image

POST /api/v1/booths/<booth_pk>/images/<image_pk>/set-primary/

Set a specific image as the primary image for a booth.

Authentication: Required

Response:

{
  "id": 1,
  "url": "https://example.com/media/booths/1/image1.jpg",
  "is_primary": true,
  "booth": 1
}

Status Codes:

  • 200 OK: Primary image set successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to modify this booth
  • 404 Not Found: Image or booth not found

Booth Videos

Create Booth Video

POST /api/v1/booths/<booth_pk>/videos/

Upload a video for a specific booth.

Authentication: Required

Request: Multipart form data:

  • video (file, required): Video file

Response:

{
  "id": 1,
  "url": "https://example.com/media/booths/1/video1.mp4",
  "is_primary": false,
  "booth": 1
}

Status Codes:

  • 201 Created: Video uploaded successfully
  • 400 Bad Request: Invalid file or data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to upload videos for this booth
  • 404 Not Found: Booth not found

Delete Booth Video

DELETE /api/v1/booths/<booth_pk>/videos/<video_pk>/

Delete a specific booth video.

Authentication: Required

Status Codes:

  • 204 No Content: Video deleted successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to delete this video
  • 404 Not Found: Video or booth not found

Set Primary Booth Video

POST /api/v1/booths/<booth_pk>/videos/<video_pk>/set-primary/

Set a specific video as the primary video for a booth.

Authentication: Required

Response:

{
  "id": 1,
  "url": "https://example.com/media/booths/1/video1.mp4",
  "is_primary": true,
  "booth": 1
}

Status Codes:

  • 200 OK: Primary video set successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to modify this booth
  • 404 Not Found: Video or booth not found

Item Images

Create Item Image

POST /api/v1/booths/<booth_pk>/items/<item_pk>/images/

Upload an image for a specific item.

Authentication: Required

Request: Multipart form data:

  • image (file, required): Image file

Response:

{
  "id": 1,
  "url": "https://example.com/media/items/1/image1.jpg",
  "is_primary": false,
  "item": 1
}

Status Codes:

  • 201 Created: Image uploaded successfully
  • 400 Bad Request: Invalid file or data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to upload images for this item
  • 404 Not Found: Item or booth not found

Delete Item Image

DELETE /api/v1/booths/<booth_pk>/items/<item_pk>/images/<image_pk>/

Delete a specific item image.

Authentication: Required

Status Codes:

  • 204 No Content: Image deleted successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to delete this image
  • 404 Not Found: Image, item, or booth not found

Set Primary Item Image

POST /api/v1/booths/<booth_pk>/items/<item_pk>/images/<image_pk>/set-primary/

Set a specific image as the primary image for an item.

Authentication: Required

Response:

{
  "id": 1,
  "url": "https://example.com/media/items/1/image1.jpg",
  "is_primary": true,
  "item": 1
}

Status Codes:

  • 200 OK: Primary image set successfully
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Not authorized to modify this item
  • 404 Not Found: Image, item, or booth not found

Error Responses

All endpoints may return error responses in the following format:

{
  "detail": "Error message describing what went wrong"
}

For validation errors, the response may include field-specific errors:

{
  "field_name": [
    "Error message for this field"
  ],
  "another_field": [
    "Error message for another field"
  ]
}

Common HTTP Status Codes

  • 200 OK: Request successful
  • 201 Created: Resource created successfully
  • 204 No Content: Resource deleted successfully
  • 400 Bad Request: Invalid request data
  • 401 Unauthorized: Authentication required or invalid token
  • 403 Forbidden: Not authorized to perform this action
  • 404 Not Found: Resource not found
  • 500 Internal Server Error: Server error

Rate Limiting

API requests may be subject to rate limiting to prevent abuse. Rate limit headers are included in responses:

  • X-RateLimit-Limit: Maximum number of requests allowed
  • X-RateLimit-Remaining: Number of requests remaining
  • X-RateLimit-Reset: Time when the rate limit resets

When rate limits are exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating when to retry.

Pagination

List endpoints may support pagination for large result sets. Pagination parameters:

  • page (integer): Page number (default: 1)
  • page_size (integer): Number of results per page (default: 20, max: 100)

Paginated responses include pagination metadata:

{
  "count": 100,
  "next": "https://example.com/api/v1/booths/list/?page=2",
  "previous": null,
  "results": [...]
}

Synchronization

The API is designed to support offline-first mobile synchronization. The mobile client uses these endpoints to:

  1. Authenticate and obtain tokens
  2. Upload locally created booths and items
  3. Download server-side updates
  4. Sync media files (images and videos)
  5. Resolve conflicts between local and server data

For detailed synchronization behavior, see the Development page.

Additional Resources

For implementation details and examples, see the server source code in server/apps/exposcholar/.


Last Updated: 2025-01-25
ExpoScholar Version: v0.9.3-beta+3