Regift · Knowledge Article
Architecture & Engineering Overview
Regift is an AI-powered, anonymous marketplace for brand-new, unopened gifts, serving all of New South Wales, Australia. It is live on the App Store and Google Play. This article is a detailed, end-to-end tour of the product: what it does, how the system is put together, the technologies behind it, and how it's deployed to production on Microsoft Azure.
Current as of release 1.0.1 (build 51), September 2026.
Contents
Product
What Regift is
Every year, mountains of perfectly good, still-sealed gifts end up forgotten in cupboards. Regift gives them a second life. Users list an unopened gift to sell, exchange, or donate, and other people nearby can browse, make an offer, chat, and arrange a safe exchange — all without ever revealing their real identity.
Three principles shape every design decision:
Anonymous by default
Safe to transact
AI does the busywork
How it fits together
System architecture
Regift is deliberately a single-service backend: one FastAPI application running on an Azure App Service (Linux, B1 tier), fronting a set of managed Azure services and third-party partners. Two Flutter apps (iOS and Android) and a web admin console are the clients. This keeps the system easy to reason about, cheap to run, and fast to deploy, while the heavy lifting (storage, realtime, push, AI) is offloaded to managed services.
The backend is stateless between requests — all state lives in Azure Storage — so it can restart or scale without losing data. Long-running work (escrow auto-release, courier tracking) runs as background daemon threads inside the same process.
Technology
Technology stack
Apps & frontend
| Layer | Technology | Role |
|---|---|---|
| Mobile apps | Flutter (Dart) | Single cross-platform codebase for iOS & Android |
| Design system | “Meadow” — Material 3 + custom widgets | Serif display + Figtree UI, glass cards, floating dock |
| Realtime | Web PubSub client + poll fallback | Live chat message delivery |
| Payments UI | Stripe SDK (PaymentSheet) | Card, Apple Pay & Google Pay checkout |
| Maps | flutter_map · CARTO basemaps (OpenStreetMap) | Browse map & safe spots; tile URL served from backend config |
| Secure storage | Platform Keychain / Keystore | Encrypted session-token storage on device |
| Admin console | Server-rendered HTML + vanilla JS | Operations dashboard served by the API |
Backend
| Layer | Technology | Role |
|---|---|---|
| API framework | FastAPI (Python) + Uvicorn worker | REST endpoints, middleware, background tasks |
| Auth | JWT session tokens + OIDC (Apple/Google) | Passwordless sign-in, per-request identity checks |
| Images | Pillow + Blob SAS URLs | Thumbnailing, share cards, time-limited image links |
| Background jobs | Daemon threads | 7-day payout auto-release, courier tracking poll |
| Limits | In-process per-IP rate limits + per-caller AI quota | 300 API requests/min per IP; 60 AI calls/hour per caller |
Microsoft Azure
| Layer | Technology | Role |
|---|---|---|
| Compute | App Service · Basic B1 (Linux) | Hosts the FastAPI service |
| Database | Table Storage (NoSQL) | Users, gifts, offers, messages, deliveries, more |
| Object storage | Blob Storage | Gift & verification images, served via SAS |
| Realtime | Web PubSub | Pushes chat messages to connected clients |
| Push | Notification Hub | Fan-out to APNs (iOS) and FCM (Android) |
| AI | Azure OpenAI · Microsoft Foundry (gpt-5-mini) | Listing composer, natural-language search, wishlist matching, support assistant |
| Delivery | GitHub Actions → App Service | CI/CD on every push to main |
External partners
| Layer | Technology | Role |
|---|---|---|
| Payments | Stripe Connect | Buyer checkout, seller payouts, escrow-style holds |
| Delivery | Transdirect | Multi-courier quotes, auto-booking & shipping labels |
| Identity (KYC) | Didit | Optional identity verification — result only |
| Sign-in | Apple Developer · Google Cloud | Sign in with Apple & Google, push credentials |
| Distribution | App Store Connect · Google Play Console | Releases scripted via the App Store Connect & Android Publisher APIs |
Capabilities
Feature catalogue
Discovery & browse
Listings
Offers & trading
Anonymous chat
Trust & safety
Payments & delivery
Wishlists & alerts
Notifications & purchases
Impact & badges
Referrals & sharing
Persistence
Data & storage model
Regift uses Azure Table Storage, a wide-column NoSQL store, rather than a relational database. Each concern gets its own table — users, gifts, offers, messages, deliveries, reports, disputes, notifications, wishlists, saved searches, and more. Tables are created automatically on first use, so a fresh environment bootstraps itself with no migration step.
Partition and row keys are chosen so common reads are single- partition and cheap — for example, notifications are partitioned by user with an inverted-timestamp row key so the newest appear first. Images live in Blob Storage and are served through short-lived signed (SAS) URLs rather than being made public.
Why NoSQL here
Anonymity in the data
Trust
Identity, anonymity & security
Sign-in is passwordless: Sign in with Apple and Google sign-in only. Provider identity tokens are validated on the server, and a signed session token is issued for subsequent requests. Session tokens are stored in the device's hardware-backed Keychain / Keystore, not in plain storage.
A security middleware runs ahead of every API request: it authenticates the caller and enforces that a signed-in user can only act on their own resources. Sensitive operations verify resource ownership (only a seller edits or deletes their listing; only a conversation participant reads its messages). Public endpoints are limited to anonymous browsing data and never leak personal contact details.
Optional KYC (Didit)
Defence in depth
Fail closed, limit abuse
Quiet production logs
Money
Payments & escrow
Payments run on Stripe Connect. Sellers complete a one-time payout onboarding (their bank details go directly to Stripe, never to Regift). When a buyer pays, the charge lands in the Regift platform account — this is the escrow hold. The seller's share is only transferred to them once the exchange completes.
Release happens when the buyer taps “I received it”, or automatically after a 7-day safety window if they never do. Before release, a full refund is always possible; after release it's handled manually. Checkout supports card, Apple Pay, and Google Pay, and item prices and postage are always taken from the server-side listing — never trusted from the client.
Stripe runs in live mode. The checkout response names the publishable key of the account that created the PaymentIntent, and the app builds its payment sheet with that key, so a key rotation needs no app release. Connect account IDs are mode-scoped: a stored account that no longer resolves under the current key is detected and cleared, so the seller is asked to onboard again instead of a buyer paying for a transfer that could never land. At start-up the server flags secret and publishable keys that belong to different modes.
Logistics
Courier delivery
For exchanges that shouldn't happen in person, Regift integrates Transdirect, a multi-courier aggregator. When a seller submits their pickup address, the backend requests quotes across couriers, auto-books the cheapest option, and stores the pickup window and estimated delivery date. The seller prints the generated shipping label and leaves the box out; the buyer sees live status and an ETA.
Coverage spans all of New South Wales, validated by postcode on both the listing and the drop-off address rather than by distance from Sydney. A configurable cost guard holds a booking for manual review if the courier quote would exceed the postage the buyer paid by more than 10%, and a background poller advances delivery status from the courier's tracking feed. A free self-ship mode lets sellers post items themselves at no cost to the buyer.
Transdirect runs in live mode, booking and confirming the cheapest real courier. A demo mode books Transdirect's test courier instead; the two are switched by a single setting, which the admin console reports back as the running server sees it.
Intelligence
AI features
AI is how Regift takes the effort out of a marketplace: the slow parts — writing a listing, finding the right gift, answering “how does this work?” — are done by models running on Azure OpenAI (gpt-5-mini, deployed through Microsoft Foundry). Four features ship in the apps today:
“Write it for me” listing composer
Natural-language search
Semantic wishlist alerts
Boxy, the support assistant
Guardrails keep it predictable and affordable: every model-backed call counts against a per-caller quota of 60 per hour, and over the limit a feature degrades gracefully (search falls back to local filtering) rather than failing. The support assistant refuses off-topic and prompt-extraction attempts with a canned reply, and App Review's demo listings are kept out of the search catalogue.
Engagement
Realtime & notifications
Chat is delivered in realtime through Azure Web PubSub, with a polling fallback so messages still arrive if the socket drops. Every notable event — new message, offer update, delivery status change, wishlist match — is delivered two ways: a push notification and a persistent entry in the in-app notification centre (retained ~90 days), so users who declined push permission still miss nothing.
Push fan-out uses Azure Notification Hub, which routes to APNs for iOS and Firebase Cloud Messaging for Android from a single backend call. Device registrations are stored per platform so a user's iPhone and Android tablet can both receive alerts. Tapping a notification deep-links to the exact conversation, offer, purchase, or listing it refers to. Deleting an account removes its device registrations on both platforms, and orphaned registrations are pruned so device counts don't drift.
Operations
Admin console
A dedicated, authenticated web console — served by the same API — gives operators everything they need to run the marketplace: a deliveries queue (with one-click courier info and status controls), a disputes workflow with permanent history, moderation tools (verify/block users, mark listings inactive with a reason, resolve reports), a funds held / released indicator on every paid order, a waitlist for out-of-area demand, and feature toggles. It also reports whether Stripe and Transdirect are in live or test mode as the running server sees them, and includes scoped tools that remove App Review demo data (with a dry run first) or a single account.
Production
Infrastructure & deployment
Regift runs entirely on a single Microsoft Azure subscription. The production environment was stood up as follows:
- Create the Azure account and a Resource Group to hold everything.
- Provision an App Service on the Basic B1 (Linux) plan to host the API.
- Add a Storage Account (Table + Blob), Web PubSub, and a Notification Hub.
- Create an Azure OpenAI resource and deploy the gpt-5-mini model via Microsoft Foundry.
- Configure all secrets and connection strings as environment variables in the Web App settings.
- Wire GitHub Actions to the Web App from both sides so every push to
mainbuilds and deploys automatically. - Set the Web App startup command:
uvicorn.workers.UvicornWorker --timeout 120 app:app. - NoSQL tables auto-create on first use — no manual schema setup.
- Populate the Notification Hub with APNs and FCM credentials: the Apple
.p8key (header/footer stripped, pasted as the token) and the Firebase service credentials.
External integrations are provisioned alongside: Apple Developer (certificates, identifiers & keys) and App Store Connect for iOS; Firebase, Google Cloud and Google Play Console for Android; Didit for KYC; Stripe Connect for payments; and Transdirect for delivery. Each is wired in through environment configuration, so the same codebase runs in test or live mode by changing settings alone.
Shipping
Releases & App Review
Both stores are released by script rather than by hand. iOS builds are uploaded to App Store Connect, and the version's metadata, review notes, build selection and submission go through the App Store Connect API. Android bundles, their R8 mapping file, the store listing text and release notes are committed in a single Android Publisher API edit that is discarded if any step fails, so a half-applied release never reaches the store.
In 1.0.1 (build 51)
One switch for App Review
REVIEWER_LOGIN_BUILD, shows the reviewer sign-in only on the build under review, opens the demo login, and restores the demo data if a reviewer deletes the account. Demo listings are visible only to the review accounts — the browse cache is keyed by audience so they never leak — and the switch is cleared once the build is approved.Configuration, not code
One QR code, both stores
vexbit.au/regift, which sends iPhones and iPads to the App Store and Android phones to Google Play, and shows both buttons anywhere else.About this article
Regift is built and operated by Vexbit, a Sydney-based AI product studio. For product help, see the Support page; for data handling, see our Privacy Policy.