Inspiration
It started with a game. We were playing 911 Operator, where you answer emergency calls, work out what's happening and where, and decide which units to send. It was fun, but partway through we started asking how much of it was real. The game boils dispatch down to a few clicks, while a real dispatcher is doing far more. They pull a location out of a panicked caller, choose who is closest and appropriate, and keep the rest of the town covered once a unit leaves.
We wanted to see what that job would look like if it were built around a real place, so we set it in Blacksburg, VA, with its actual stations and streets. Then we asked what happens when the dispatcher is already on another line. That led to the AI operator, a voice agent that picks up first, gets the details, and passes them to a human.
What it does
Gridline has three parts.
1. Report an Emergency (public, no sign-in)
A caller shares their location, then either talks to an AI dispatch operator or types a short note.
- The AI operator is an ElevenLabs Conversational AI agent, and the call happens live in the browser
- The report appears on the dispatcher's board the moment the call starts, with the caller's real GPS location
- Callers can update their location if they move
- The report page is built for phones and only sends information, so callers never see units or anyone else's report
2. Operator Dashboard (password-gated)
A live dispatch console for Blacksburg.
- A queue of simulated 911 calls tied to real intersections, plus live citizen reports
- The dispatcher chooses exactly which units respond
- Units drive real roads using OSRM routes, so ETAs are real drive times
- Police patrol beats, EMS rotates between posts, and fire apparatus stays in quarters, just like the real services
- Units stay committed until cleared, then return to their beat or station
- Coverage move-ups: commit an engine and the other station's engine slides over to cover the gap, and commit a medic and the other shifts to cover that district
- AI call notes appear next to each call after it ends
- If nobody has dispatched, the backend sends the nearest suitable unit on its own
- The AI can also dispatch live during the call through a server tool, so it can tell the caller a cruiser is about six minutes out
- Real stations: Blacksburg PD, both Blacksburg Volunteer Fire Department stations, the Blacksburg Volunteer Rescue Squad, and LewisGale Hospital Montgomery, each placed from a published address
3. Gridline Scan (floor plan to 3D)
Upload a floor plan and get a walkable 3D model of the building.
- Runs entirely in the browser with no backend
- The file is never uploaded anywhere
- The idea is that a dispatcher could look at a building's layout before sending crews
How we built it
- Backend: Java 17 and Spring Boot for the intersection and station registries, responder state, dispatch and ETA logic, move-up coverage, the citizen report API, and the ElevenLabs webhook and dispatch-tool endpoints
- Frontend: React with Vite
- Map: MapLibre GL JS with OpenFreeMap vector tiles and 3D building tilt
- Routing: the public OSRM driving API, with a straight-line fallback if it's unreachable
- Voice AI: ElevenLabs Conversational AI through the @elevenlabs/react SDK, with the report code and location passed to the agent as variables and the post-call webhook writing the summary back to the dispatcher's board
- Scan: a single self-contained HTML file built with three.js
- Deployment: the frontend is a static site on Cloudflare at gridline.wiki, and the backend runs as a Docker container on Render
Challenges we ran into
- Making units behave like real services. One generic "wander around" behavior looked wrong, so we gave police, EMS and fire their own patterns and added move-up coverage.
- Keeping dispatch and animation consistent. The server decides who is committed while the browser owns where a unit appears on screen. Merging the two stopped units from snapping back to old positions.
- Two ways for the AI to dispatch. Live dispatch through a server tool could race with the post-call fallback. The fallback now skips itself if a unit is already responding, so a call never ends up with two units committed.
- Keeping a running shift alive. Visiting the Scan dashboard shouldn't wipe the call queue or a live voice call, so we hide screens instead of unmounting them and pause the 3D scene while it's out of view.
- Making the public page mobile-ready. Callers will be on phones, so it needed thumb-sized buttons, form text that doesn't trigger zoom on iPhones, and a call view that keeps the End Call button on screen.
Accomplishments that we're proud of
- A caller can talk to an AI operator and have a real unit dispatched on real roads, all in one flow
- Units follow the patterns real services use, including coverage move-ups
- The dashboard, the public report page and Scan share one design language
- Scan works with zero network requests
What we learned
- Emergency dispatch is a coverage problem as much as a routing problem, because every unit you send opens a gap somewhere else
- Voice AI works best as the first responder on the line rather than a replacement for the human dispatcher
- Real data, like published station addresses and the actual street network, makes a demo far more convincing than fake data
What's next for Gridline
- Move the patrol simulation to the backend so multiple consoles stay in sync
- Add real authentication, since the demo's password gate and API are only UI-level
- Use a self-hosted routing engine instead of the public OSRM demo server
- Connect Scan's building models to incoming calls so a dispatcher can see the layout of an address
Gridline is a demo and not a real emergency line, and the report page says so.
Built With
- cloudflare
- elevenlabs
- java
- maplibre
- openfreemap
- react
- spring-boot
- vite
Log in or sign up for Devpost to join the conversation.