Inspiration
Traditional leaderboard systems are effective at tracking scores, but they often feel static and disconnected from real user engagement. We wanted to build a leaderboard-first platform that feels more interactive, social, and fun. That led us to Pawdium, where themed pet posts and community likes turn everyday interaction into a live ranking experience.
What it does
Pawdium is an leaderboard platform where students and faculty can share themed pet posts, explore a community feed, and compete on a live monthly leaderboard. Users can upload posts based on a monthly theme, receive likes from others, and see rankings update dynamically based on engagement. To keep the competition fair, only each user’s highest-liked post is counted toward the monthly leaderboard.
How we built#
We built Pawdium using FastAPI as our backend framework with SQLite as the database. The server exposes a fully REST-compliant API, documented with OpenAPI 3.0 and accessible through Swagger UI. The frontend is built with vanilla HTML, CSS, and JavaScript — communicating with the server entirely through REST API calls
Live Demo
--> Click here Hosted URL: https://unhurryingly-interconsonantal-vonda.ngrok-free.dev
Because it's free version, you have to click visit site to get in!
GitHub: https://github.com/gk11-creator/Pawdium
REST API Endpoints
Required Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/add |
Add or update a leaderboard entry |
DELETE |
/remove |
Remove a user and all their posts |
GET |
/leaderboard |
Returns top 10 leaderboard (HTML page) |
GET |
/info |
Returns statistics: mean, median, Q1, Q3, IQR |
GET |
/performance |
Returns average endpoint execution time (ms) |
Additional Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/register |
Register a new user |
POST |
/login |
Login with username and password |
POST |
/upload |
Upload a pet photo post |
GET |
/posts |
Get all posts (filterable by username) |
POST |
/like/{post_id} |
Like or unlike a post (toggle) |
GET |
/liked/{username} |
Get all post IDs liked by a user |
POST |
/comment/{post_id} |
Add a comment to a post |
GET |
/comments/{post_id} |
Get all comments for a post |
DELETE |
/post/{post_id} |
Delete a post (owner only) |
GET |
/missions |
Get today's daily missions |
GET |
/missions/{username} |
Get missions with completion status |
GET |
/api/leaderboard |
Get full leaderboard as JSON |
GET |
/history |
Score submission history with timestamps and filtering |
GET |
/profile/{username} |
Get user profile |
PUT |
/profile/{username} |
Update user profile |
Ranking System
Pawdium uses a multi-factor scoring system to rank pets:
Viral Score
Calculated on every like based on recent activity:
| Likes within 1 hour | Multiplier |
|---|---|
| 10+ likes | x1.5 |
| 20+ likes | x2.0 |
| 50+ likes | x3.0 |
Bonus Points
Earned by completing daily missions:
| Mission | Description | Points |
|---|---|---|
| Daily Post | Upload 1 post today | +1 |
| Like Spree | Like 5 different posts today | +1 |
| Chatterbox | Leave 3 comments today | +1 |
| Viral Star | Get 5 likes within 1 hour | +5 |
| Fan Favorite | Get 10 total likes on your post | +7 |
| Conversation King | Get 5 comments on your post | +3 |
| Theme Champion | Post with this month's theme | +5 |
| Theme Supporter | Like 3 posts with this month's theme | +1 |
Final Score = viral_score + bonus_points
Only the best post per user (most liked) is counted toward the leaderboard.
Statistics (/info)
Returns the following metrics for all posts:
- Mean, Median, Min, Max
- Q1, Q3, IQR
- Average & Max Viral Score
Project Structure
Pawdium/
├── server.py # FastAPI backend + all REST API endpoints
├── openapi.yaml # OpenAPI 3.0 API specification
├── requirements.txt # Python dependencies
├── pawrank.db # SQLite database
├── uploads/ # Uploaded pet images
└── static/
├── login.html # Login & register page
├── feed.html # Community feed
├── post.html # Upload post with crop tool
├── leaderboard.html # Real-time leaderboard + missions
├── profile.html # User profile + mission status
├── style.css # Global styles
├── feed.css # Feed-specific styles
└── images/
├── paw-heart.png
├── paw-heart-filled.png
├── pawdium-logo.png
├── home.png
├── ranking.png
└── profile.png
Challenges we ran into
Profile images not showing up on feed posts — fixed by joining the users table when fetching posts Liked posts not persisting after page refresh — solved by adding a /liked/{username} endpoint Rankings were unfair for users with multiple posts — changed to only count each user's best post Database locking issues when multiple users interacted simultaneously
Accomplishments that we're proud of
Built a fully REST-compliant API with all required endpoints Implemented a multi-factor viral scoring algorithm that updates in real time Created a daily mission system that drives user engagement and generates richer data Built a photo crop and positioning tool from scratch with no libraries Designed a clean, cohesive UI with an earth-tone aesthetic
What we learned
How to design and implement a REST API following OpenAPI 3.0 standards How to manage real-time data updates with SQLite How to build a scoring algorithm that balances multiple factors How to handle concurrent database access in a web server
What's next for Pawdium
Docker containerization for reproducible deployment Monthly season resets with Hall of Fame for past winners Mobile app version More advanced scoring using the formula: popularity, momentum, consistency, quality, and diversity
Log in or sign up for Devpost to join the conversation.