Inspiration
Every year, strong students accept the wrong offer for one simple reason: the offers can't see each other.
Imagine Daniel. He has two offers for a master's in Finance. University A offers a 0% scholarship, University B offers 25%. A would happily have paid 50% to get him, but it never knew B was bidding. Daniel can't negotiate, so he takes B's cheaper seat, and A loses a student it wanted without ever finding out why.
Scholarships are already a price for talent. Today that price is set blind, by fixed criteria, and the student has no leverage. We asked a simple question: what if admissions worked the other way round?
For decades, students have competed for universities. We flipped it: universities compete for students.
What it does
FlipAdmit is a reverse admissions marketplace.
- Students upload a CV, a statement of purpose and up to three references as PDFs, once. AI reads them, summarises the profile and suggests courses they might not have considered. Students set their priorities: up to 3 courses, a minimum university ranking and a maximum tuition fee. They pay a one-time £100 fee, refunded in full if nobody bids.
- Universities add courses with a description, seats and a scholarship fund. Matching students appear ranked by fit, each with an AI brief explaining the rank. Universities make offers: a scholarship plus perks such as accommodation or a paid placement year.
- Three rounds. Each round, a university can raise its offer once. Offers can never be lowered or withdrawn. Universities see how many rival offers a student has and the highest scholarship among them, so they know when they're losing.
- The student decides. Offers are ranked by value. One click accepts, every other offer closes automatically, and £90 of the fee becomes a deposit at the chosen university.
How we built it
Stack: Next.js 15 and TypeScript, PostgreSQL with Drizzle ORM, Nebius AI (gpt-oss-120b and Qwen3-Embedding-8B), Nodemailer, unpdf and Tailwind CSS.
Our main design rule was: AI reads and explains; code decides. Anything involving language goes to the models. Anything involving money, seats or rules is deterministic code inside database transactions, and a person confirms every offer.
Ranking students for a course
Each student's documents and each course description are embedded, and their cosine similarity is mapped to a semantic score $s \in [0, 1]$. We blend that with how the course's subject relates to the student's stated preferences:
$$ \text{fit} = 100 \times \big( 0.7\,s + 0.3\,w_r \big), \qquad w_r = \begin{cases} 1.0 & \text{exact match with a preference} \ 0.85 & \text{an area the AI suggested} \ 0.7 & \text{related subject (e.g. AI within Computer Science)} \ 0.2 & \text{unrelated} \end{cases} $$
Subjects are grouped into fields, so a student who wants Computer Science still reaches a university's MSc in Artificial Intelligence.
Offers and funds
Scholarships come in fixed steps $p \in {0, 25, 50, 75, 100}\%$ of annual tuition $T$, over a course of $y$ years. Each offer reserves its full value against the course's fund $F$:
$$ \text{offer value} = \frac{p}{100}\, T\, y, \qquad \sum_{\text{open + accepted offers}} \text{offer value} \;\le\; F $$
In each round, an offer can only move upwards: $p_{\text{new}} \ge p_{\text{old}}$, and perks can be added but never removed. When tuition is above a student's budget $B$, the university is shown the smallest scholarship that closes the gap, $p_{\min} = \left\lceil 100 \cdot \tfrac{T - B}{T} \right\rceil\%$.
Trust and money
- Every offer and acceptance locks the course's row inside a transaction (
SELECT … FOR UPDATE), so two universities can never take the same last seat or spend the same pound. - Payments use double-entry bookkeeping: every movement writes entries where $\sum \text{debits} = \sum \text{credits}$. The £100 fee is held in escrow until the student accepts an offer or the cycle closes.
- Accounts use scrypt password hashing, database sessions, and a one-time email code on every sign-in. Universities must sign up with an
.ac.ukaddress. - Every AI call is cached by a hash of its input, validated against a schema, capped by a daily budget, and backed by a non-AI fallback, so the demo can't break on stage.
We used Claude as a coding and design assistant throughout, and reviewed and tested everything ourselves.
Challenges we ran into
- Database tooling. Our first plan was Prisma, but its engine downloads were blocked in our build environment. Our first fallback was a native SQLite driver, which then failed to compile on a teammate's Windows laptop on an old Node version. We moved to PGlite, real Postgres compiled to WebAssembly: no installs, nothing to compile, and the same code runs against a hosted Postgres by setting one variable.
- Real-world PDFs. Our first PDF parser crashed on ordinary CVs ("bad XRef entry"). Switching to
unpdf, built on a modern PDF.js, fixed it. - Designing a fair auction. Free-form bids let universities signal with odd numbers and made offers hard to compare. Fixed scholarship steps, one change per round and raise-only rules turned out to be simpler for everyone and harder to game.
- Edge cases in a two-sided market. Two universities racing for the last seat, a student accepting while an offer is being raised, refunds when nothing is accepted. Each needed a rule enforced in the database, not just a check in the UI.
- Our first interface was cluttered. We had built every feature from the spec and the screens showed it. We rebuilt the UI around one main action per screen.
Accomplishments that we're proud of
- The flip works end to end. A student uploads real PDFs, gets ranked, receives an offer, watches a rival raise it in the next round and accepts with one click. Every step runs on real data, with no seeded or fake records.
- Real accounts, not a role switcher. Sign-up with email verification, a one-time code on every sign-in, password reset by email, and
.ac.ukchecks for universities. - A safe auction. Seats and scholarship funds can't be over-committed, even when two universities act at the same moment, because the rules live in database transactions.
- Honest money. The test-mode payment flow writes a double-entry ledger that always balances: escrow, the £10 platform fee, the £90 deposit to the chosen university and automatic refunds.
- AI that can't break the demo. Every AI feature is cached, cost-capped and has a fallback. The app runs fully without an API key and gets smarter with one.
- Zero-setup install.
npm installandnpm run devgive a working app with a real Postgres database on Windows, macOS or Linux. - An accessible, simple interface. Keyboard-friendly dialogs, visible focus, plain-language errors and one clear action per screen.
What we learned
- Where AI belongs. Language models are excellent at reading a CV and explaining a ranking, and the wrong tool for deciding money. Keeping that line sharp made the product cheaper, more predictable and easier to defend under UK GDPR, which limits decisions made solely by automated systems.
- Fallbacks are a feature. Designing every AI step to degrade gracefully meant we could demo with or without credits.
- Concurrency is a product decision. "What happens if two people click at once?" turned out to be one of our most important design questions.
- Flipping a system changes what's fair. Once universities bid, we had to think about transparency for students, signals between rival universities, and who pays the fee.
What's next for Flip Admit
- Real payments through a marketplace provider such as Stripe Connect, so the deposit reaches the university without us holding funds.
- Scheduled rounds that open and close on set dates instead of by an admin.
- Verified rankings and accounts, checking each university's ranking and its admissions team.
- A postgraduate pilot with a few universities and one subject, such as Computer Science master's. UK undergraduate admissions run through UCAS, so they would need a partnership.
- Fairness monitoring: tracking offer rates and scholarship sizes by background, and flagging gaps between groups.
Universities compete. Students hold the cards.
Built With
- nebius
- next.js
- node.js
- postgresql
- react
- typescript
Log in or sign up for Devpost to join the conversation.