YesTonite - Trust and safety for a dating app
How we built trust and safety into YesTonite, a dating app without matching: age and e-mail checks, sign-in protection, fast reporting and moderation, and the reviews that payment providers and app stores require.
Part 3 of the YesTonite series. New here? Start with the main case study: YesTonite - Building a casual dating app for web and Android.
Project snapshot
|
Field |
Detail |
|---|---|
|
Project |
YesTonite: trust and safety |
|
Type |
Client project · safety, verification, moderation and compliance |
|
Client |
City Dev, the Netherlands (operator of YesTonite) |
|
Industry |
Online dating and social discovery (18+) |
|
Built |
2026 |
|
Timeline |
About one week to the live web app · Android in Google Play closed testing from mid-October 2026 |
|
Started |
6 October 2026 |
|
Team |
1 CTO, 1 developer, 1 designer |
|
Delivery |
Built end to end by techlead.fit, including the policy documents |
|
Status |
Live on the web and in the Android test build · Stripe review answered · Google Play child safety declaration submitted · 18+ image detection in preparation |
|
Stack |
Directus 12 · PostgreSQL · Next.js 16 · Expo SDK 57 · Amazon SES and SNS · IP geolocation |
The situation
YesTonite lets adults see who is nearby and open to meeting tonight. There is no match: one message opens the chat.
In a classic dating app, the match acts as a filter. Both people have to agree before anyone can write. YesTonite removes that filter on purpose, because it is what makes the product fast and simple.
That puts the responsibility somewhere else. The system has to keep minors out, protect accounts, stop unwanted contact quickly, and give the operator the tools to act.
It also has to convince two gatekeepers. Payment providers treat dating as a restricted business. App stores have specific policies for dating apps and child safety.
The challenge
Safety features in consumer apps tend to fail in one of two ways. Either they are so strict that honest people give up during sign-up, or they live only in the screens, where anyone with a modified client can skip them.
We needed protection that holds on the server, stays out of the way for the honest majority, and can be explained clearly to Stripe and Google.
Decisions before code
Every rule on the server. The age limit, e-mail confirmation and sign-in checks are enforced by the backend. The web app and the Android app only show the screens.
Share less by default. Names are private until a member shares theirs in a chat. Only an approximate distance is shown, never an exact location. Event addresses unlock only for people who are in.
Ask for proof only when something is unusual. A sign-in from a known country goes straight through. A sign-in from a new country needs a code.
Reports act first, review second. The most serious reports hide an account immediately. A person reviews afterwards.
Write the policies as part of the product. Child safety standards, an acceptable use policy and guidelines for law enforcement were written alongside the features they describe.
Texts say what to do, not how it works. Members see clear, short instructions. The technical detail stays in the backend.
How it works
1. Adults only
The birthday is checked on the server during onboarding. Under 18 means no account, whatever the client sends.
2. Confirm the e-mail
New members confirm their e-mail with a 6-digit code or a one-click link. Codes have a cooldown and an hourly limit, and wrong attempts are counted.
The link had one detail that matters in practice. Corporate mail scanners open links to check them. If opening the link were enough, a scanner would confirm the account for you. So the link opens a page, and the page confirms only after it has loaded in a real browser. A plain visit to the address never confirms anything.
3. Protect the sign-in
When someone signs in from a country the account has not used before, the backend asks for a code sent to the member's e-mail. The e-mail also has a one-click "Yes, it's me" button.
At the same time, the member's other signed-in devices show an alert: "New login from" the country, the time, web or app, and a world map with a dot on the approximate location. Two buttons: "That was me" or "It wasn't me".
"It wasn't me" stops only that new session. The member's own devices stay signed in, and they are advised to change their password. A pending sign-in that nobody confirms runs out after 24 hours and its session is ended.
4. Block and report
Members can block or report anyone in two taps, from a profile, a chat or an event. A report blocks by default, so the two people stop seeing each other at once.
Reports for an underage member or a safety threat put the reported account under review immediately, which hides it from everyone. For other reasons, an account goes under review when several different people report it within a set window. City Dev can change the reasons, the threshold and the window in Directus Studio.
5. Moderate
Moderators work in Directus Studio: dismiss, warn, suspend, ban or reinstate. Banning a host also cancels their future events. Moderators get a digest of open reports, and suspensions end by themselves when their time is up.
6. Protect what is on screen
On Android, screenshots and screen recording are blocked on screens that show other members.
The build
The verification flow is one backend module with its own sign-in and refresh endpoints, which replace the default ones for members. Every other member call passes a gate that checks whether the e-mail is confirmed and whether the current sign-in is still pending.
Both clients follow one written specification: the same screens, the same texts and the same rules on web and Android. The specification lists every error and the exact message the member sees.
E-mail runs through Amazon SES, with bounce and complaint notifications handled through SNS so bad addresses stop receiving mail. While SES production access is pending, a temporary mail provider sends the messages.
Old codes and sign-in records are cleaned up on a schedule, so the system keeps only what it needs.
Compliance work
-
Stripe's restricted business review for dating, answered with the documented protocols for age, reporting, moderation and law enforcement requests.
-
Google Play's child safety declaration, backed by published child safety standards with a named point of contact.
-
Public pages for the acceptable use policy and law enforcement guidelines, next to the terms and privacy policy.
In preparation
Detection of 18+ images is in preparation on a separate branch. It combines a check on the device with a check on the server, using an open-source model. It is not live yet.
Testing and validation
-
The backend smoke test covers reports, blocking and the moderation states end to end, including that an account under review can no longer open chats.
-
The confirmation and sign-in flows were checked against the written specification on both web and Android, error by error.
-
The Android test build is used by real testers in Google Play closed testing.
Outcome
YesTonite runs with age, e-mail and sign-in checks enforced on the server, two-tap reporting and blocking, instant hiding for the most serious reports, and moderation tools the operator uses without a developer.
Stripe's review for the dating category was answered with documented protocols. The Google Play child safety declaration is in place for the Android launch.
What we learned
Friction belongs where risk is. Most sign-ins never see a code. A sign-in from a new country does, and that one step protects the account without bothering anyone else.
Mail scanners are real users of your links. A confirmation link that confirms on a plain visit will be confirmed by software. Designing for that up front avoided a confusing bug in production.
Let the member stop one session, not all of them. "It wasn't me" ending only the unknown session means the real owner is never locked out of their own phone.
Policies are faster to write next to the code. When the reviewers asked how reports and age are handled, the answers already existed as documents that matched the system.
Why this is a techlead.fit case study
Trust and safety is often left until a payment provider or app store asks for it. At that point, it is a rush.
On YesTonite we treated it as part of the product from the start: rules on the server, less data shared by default, checks only where the risk is, fast action on serious reports, and written policies that match the system.
Decide the rules.
Enforce them on the server.
Keep friction where the risk is.
Document what you built.
The YesTonite series
-
Part 1: YesTonite - Building a casual dating app for web and Android
-
Part 2: Global from day one: 44 languages and regional pricing in 63 countries
-
Part 3: Trust and safety for a dating app (this post)
-
Part 6: A growth engine without an ad budget, and the first round
Building a product where safety matters?
If your product connects people, handles payments in a restricted category, or has to pass app store review, the safety and compliance decisions shape the whole architecture.
At techlead.fit, we define those rules before development, build them into the system, and prepare the documents that reviewers ask for.
Relevant services: CTO Sprint · MVP Build