AmbuQuik — dispatch software where minutes are the metric.
An on-demand ambulance booking and emergency transport platform: a patient app, a driver app and a dispatch console, sitting on a real-time backend that finds the nearest available ambulance in expanding rings — and escalates automatically when an SOS goes unanswered.

- Domain
- Emergency medical transport
- Surfaces
- Patient app, driver app, console
- Core build
- Flutter · GraphQL · Redis
- Status
- Built & deployment-ready
Booking a cab and booking an ambulance are not the same problem.
The surface resemblance is obvious — a map, a pickup point, a nearby vehicle. But the failure modes are completely different. If a cab request finds no driver, the rider waits and tries again. If an ambulance request finds no driver, that is the emergency.
So the system had to be built around what happens when things don't go smoothly: no driver in range, a driver who doesn't respond, an SOS raised mid-trip, a dispatcher who hasn't acknowledged an alert. Each of those needed an explicit, time-bounded answer in code — not a retry button.
The second requirement was a human in the loop. Emergencies arrive by phone call as often as by app, so the console had to let a dispatcher place a booking on a caller's behalf and watch it through to completion.
The design principle: every path where the system could stall silently gets a deadline and an automatic next action. Nothing waits forever for a human to notice.
Nearest first, then wider — on a clock.
Matching runs as a continuous service rather than a one-shot query. It searches geospatially, offers to one driver at a time, and widens the net when nobody takes it.
Search the inner ring
A Redis geospatial index returns available ambulances closest to the pickup point, ranked by real distance.
Offer, with a timer
The request goes to one driver with a 30-second window. No answer is treated as a decline — the offer moves on rather than stalling.
Widen the radius
If the ring is exhausted, the search grows outward in 3 km steps up to a 15 km ceiling, picking up ambulances further out.
Fail loudly, not silently
An overall 5-minute ceiling ends the search and surfaces it, so a request can never sit unmatched and unnoticed.
Event-driven, so it reacts in milliseconds instead of polling.
Driver locations stream continuously into a Redis geospatial index, which answers “who is near this point right now” without touching the primary database. New orders and driver rejections publish onto Redis pub/sub channels, so the matcher reacts to events the moment they happen rather than waiting for its next sweep.
Because it runs on shared Redis state rather than in-process memory, the matcher scales horizontally — more instances can run behind the same queue without two of them offering the same ambulance to two different patients.
Trip updates reach the apps over GraphQL subscriptions on WebSockets, so the patient's map moves as the ambulance moves, with no polling and no stale positions.
An alarm that escalates itself.
An SOS raised from inside a trip enters a state machine with hard deadlines at every stage. If a stage's clock expires, the alert escalates on its own — it never sits quietly in a queue waiting to be seen.
To acknowledge
From the moment the alert is raised, someone must pick it up. Past two minutes it escalates to the next tier.
To dispatch
Acknowledged isn't handled. If no action has been dispatched within five minutes, it escalates again.
To resolve
The alert stays open, and keeps escalating, until it is explicitly resolved — with every step recorded.
Every alert leaves a paper trail.
Each SOS carries an activity log — who acknowledged it, when, what was dispatched, and how it closed. A supervisor reviewing an incident afterwards can reconstruct the full timeline instead of reasoning from memory.
The escalation service sweeps every 30 seconds, so a breached deadline is caught within half a minute of expiring rather than at the next shift change. Admin actions across the platform are recorded in a separate audit log.
Patient, driver, dispatcher — three apps, one backend.
Each surface talks to its own GraphQL schema. A patient's API simply doesn't contain the fields a dispatcher can reach, so role separation is enforced at the schema boundary rather than patched in with per-field checks.
AmbuQuik
Book an ambulance in a few taps, then watch it approach in real time.
- Phone + OTP sign-in
- Waypoint picking with fare preview
- Vehicle tiers and paid add-ons like a stretcher
- Live tracking with in-trip chat
- In-trip SOS
- Scheduled bookings for planned hospital visits
- Saved addresses, wallet, coupons, trip history
AmbuQuik Driver
Go online, take the job, and keep the map moving without touching the phone.
- Online/offline duty toggle
- Incoming requests with a live countdown
- Background location streaming, screen kept awake
- Hand-off to the driver's preferred nav app
- Document and vehicle verification at sign-up
- Earnings, payout accounts and trip history
Dispatch console
The control room — and the reason a phone call can become a booking.
- Manual booking on a caller's behalf
- Live order board and SOS alert queue
- Driver, patient and fleet management
- Service tiers, zones and surge pricing
- Payouts, complaints and marketing campaigns
- Role-based operator permissions and audit log
Fares, wallets and payouts, built for how operators actually run.
Zone-aware pricing. Fares combine a base charge, per-kilometre and per-minute rates and a minimum fare, configurable per vehicle tier and overridable per geographic zone with a surge multiplier — because a city centre and an outlying district don't cost the same to serve.
Prepaid dispatch. Ambulance services are configured to take payment before an ambulance is assigned, so the order lifecycle has an explicit awaiting-payment state ahead of the search — a deliberate difference from the ride-hailing default of pay-on-arrival.
Money that moves both ways. Patient wallets with top-up, coupons and gift cards on one side; driver earnings, payout accounts and payout sessions on the other, with fleet operators holding their own balances. Payments run through PhonePe with server-side checksum verification.
Two-way ratings. Patients rate drivers and drivers rate patients against review parameters the operator configures, rather than a fixed star scale nobody can tune.
What it's built on
Mobile Apps
- Flutter · Dart
- flutter_bloc + hydrated state
- get_it / injectable DI
- Typed GraphQL codegen
- Geolocation & background location
- Firebase messaging, analytics, Crashlytics
Backend
- Node.js · TypeScript
- Apollo Server 4 (GraphQL)
- WebSocket subscriptions
- Prisma ORM over SQL
- Redis — pub/sub, GEO, cache
- BullMQ background queues
Console & Infra
- React + Vite + TypeScript
- Tailwind CSS · TanStack Query
- Google Maps · Recharts
- Docker Compose (API, SQL, Redis)
- AWS S3 · PhonePe payments
- Multi-provider SMS/OTP
Need real-time dispatch, tracking or field operations?
Ambulances, service technicians, logistics fleets — the hard parts are the same: who's nearest, who's free, and what happens when nobody answers.