Freebee

Privacy

The short version: Freebee stores only what it needs to let you give and receive things, and we don’t share your data with advertisers or analytics providers.

The long version is below — what we collect, where it’s stored, and which third parties touch it.

Your account

WhatWhere it livesWhy
Name, email, cityOur Postgres database (hosted on Vercel)To identify you, send you account email, and show your listings to neighbours in the same city.
Phone number — optionalOur Postgres databaseIf you add one at signup, it lets the first three people in line on your freebie reach you on WhatsApp instead of by email. Leave it blank and those people get an email button instead. Only people in the top 3 of a line on one of your listings see it, and only while that listing is active.
Passkey credential — public key, credential ID, device metadataOur Postgres databaseTo sign you in. Your biometric and the matching private key never leave your device — we only see the public half.
Recovery codes (hashed)Our Postgres databaseSo you can recover your account if you lose every passkey. We store one-way hashes; the plaintext is shown to you once and never re-displayable.
Email verification tokensOur Postgres databaseShort-lived tokens emitted when you click the verification link in your email. Discarded after use or expiry.
Default pickup details (location, time window, notes) — optionalOur Postgres databaseIf you tick “save these as my defaults” when accepting an offer, we keep them on your user row so future accepts pre-fill. You can change or clear them by entering new defaults on the next accept.

Things you post

WhatWhere it livesWhy
Items you post — title, category, description, photo, alt text, neighbourhood, conditionPostgres (text) + Vercel Blob (photos)To show your listing to other users, and to make the photo usable for screen-reader users via its alt text. We also build a full-text search vector over these fields so other neighbours can find them.
Exact pickup spot you attach to a listing (label + coordinates) — optionalOur Postgres databaseIf you search and pick a precise spot on /post, we store its address label and map coordinates so the listing can show neighbours exactly where to collect the freebie. Leave it blank and we store nothing — the coarse town is enough. The text you type to search is sent to OpenStreetMap (see Third parties).
Hashtags parsed from your title and descriptionOur Postgres database (tags + item_tags tables)To make listings filterable by #tag and to populate the popular-tag chips on the recents and post pages. Tag slugs are derived from your text — we don't infer extra tags about you.
Offers you make on others' listingsOur Postgres databaseSo the item's owner can see who's interested, in first-come-first-served order, and pick a recipient. If you're in the top 3 of the line, you can also message the owner directly via WhatsApp or email — those messages go through your own WhatsApp/mail app, not our servers.
Pickup details an owner attaches when accepting your offerOur Postgres databaseSo the chosen recipient can see where, when, and how to pick the item up. Visible only to that recipient and the owner.
Items you favouriteOur Postgres database (favorites table)To populate your /saved page and remember which hearts to render as filled. Other users can't see what you've saved.
Saved-search alerts (city, category, query) and the notifications they fireOur Postgres database (alert_subscriptions + notifications tables)To send you offer / accept / alert-match notifications. Only you see your own alerts and notifications.
Browser push subscriptions (endpoint, p256dh, auth, user-agent)Our Postgres database (push_subscriptions table)If you opted into browser push, we keep the push endpoint so we can dispatch the same notifications to your device's OS notification tray. Dead endpoints are pruned automatically when delivery fails.
Reports you file on a listingOur Postgres databaseFor moderation. Reports retain the reporter's user ID so we can follow up if needed.

Operational data

WhatWhere it livesWhy
IP addressUsed transiently as a rate-limit key in Postgres; rows older than the longest window (~1 hour) are pruned.To stop abuse of public endpoints (login, signup, email send).
Session cookieAn HTTP-only cookie on your browserTo keep you signed in. No tracking, no third-party analytics cookies.
Server logsVercel runtime logs (retained per Vercel's policy)Debugging and security. Logs include request metadata; we try not to log sensitive payloads.

Third parties

WhatWhere it livesWhy
VercelHosting, Postgres, Blob, runtime logs, AI GatewayOur infrastructure provider. Subject to Vercel's privacy policy.
Vercel AI Gateway → Anthropic ClaudeAI-assisted listing descriptions and photo alt textWhen you use “Describe this with AI” on /post, we send the (downsized) photo and any draft text you've typed to Anthropic via Vercel AI Gateway. The model returns a suggested title, category, condition rating, description, tags, and screen-reader alt text. We also ran a one-time backfill on listings posted before the alt-text field existed: each pre-existing photo was sent to the same model to mint alt text retroactively. We don't persist anything on Anthropic's end — but the requests are processed by them.
Web Push providers (Mozilla autopush, Apple APNs, Google FCM, etc.)Browser push deliveryWhen you opt into browser push, your browser hands us an endpoint URL pointing at its push provider. To deliver a notification we sign a request to that endpoint with our VAPID key. The payload is end-to-end encrypted to your device — the push provider only sees ciphertext.
ResendOutbound and inbound emailWe hand your email address and message bodies to Resend so they can deliver mail on our behalf. This covers account mail (verification links, passkey and recovery-code security notices), replies forwarded back to the original sender, and — only if you turn them on under Notifications — opt-in alerts when someone offers to take your freebie, when your offer is accepted, when a new freebie matches a saved alert, and when a freebie you were in line for becomes available again. These notification emails are off by default and only ever sent to a verified address; manage them any time on the Notifications page.
OpenStreetMap (Nominatim geocoder)Optional “exact pickup spot” address search on /postAs you type in the pickup-spot box, we send that text to OpenStreetMap's Nominatim service through our server to fetch matching addresses. We pass only the search text and our app identifier — no account info. If you don't use the field, nothing is sent. Subject to the OpenStreetMap Foundation's privacy policy.
Google FontsSelf-hosted at build time via next/fontFonts are downloaded at build and served from our origin — Google does not see your visit.

Your choices

  • Delete your account from your profile page. That removes your user record, passkeys, recovery codes, offers, favorites, saved alerts, notifications, push subscriptions, and item listings.
  • Disable browser push at any time from the toggle on /notifications. Your stored subscription is dropped from our DB on disable.
  • Remove individual saved alerts from the same page.
  • Photos uploaded to Vercel Blob are deleted when the corresponding listing is removed.
  • For anything else, contact us.

Freebee is a small project, not a company. This page describes what the code actually does — if you spot a discrepancy, please tell us.