Soterra

Soterra is an AI phone hotline for disaster information, built at Cal Hacks 13. Call a normal US phone number, ask what is happening near you, and get answers from official sources.

Landing page: soterra-calhacks13.netlify.app

Try it now: Call +1 (712) 600-3362

Made By: Alonso, Hikaru, Dhweya, and Leia :)


Inspiration

Our grandparents live in India and Japan. When a disaster hits near them, we worry. Are they okay? Do they know what is happening?

We have also felt this panic from the other side. During a storm that knocked out our power and internet, our grandparents called us for advice, and we had no answers. Websites crawled on low-power phones, which made apps and maps useless.

When a disaster hits, the people who need answers the most are often the ones who cannot get them, because official alerts often fail. A ProPublica investigation found that emergency managers often do not send warnings through the federal Wireless Emergency Alerts system (IPAWS). Reasons include high software costs, weak training, and fear of false alarms. In more than 15 major federally declared disasters since 2016, including deadly fires and flash floods, alerts came late, came after the damage began, or never came at all. Disaster coordinator Art Botterell said it best: "The most common mode of warning system failure is failure to initiate warnings in the first place."

When alerts fail, people have to pull the information themselves. They call family, refresh social media, or watch the news, and rumors and broken networks make that even harder. Nobody should have to dig through scattered agency websites during a crisis. They should be able to call a number and ask.

That is why we built Soterra. It works from any phone, and you do not need an app or an internet connection to use it. Every answer comes from an official source, and Soterra names the source and the time so you know what to trust. If it does not know yet, it says so, and it calls you back as soon as a verified update arrives.


What it does

Soterra is an AI voice agent on a regular phone number. Behind it, a live pipeline watches official US emergency sources.

On a call

  • Works on any phone. It is a normal voice call. You do not need an app, an account, or a data connection.
  • Safety check first. On every turn, a fixed danger check runs before search or the AI. If it finds a match, the caller hears a scripted "hang up and dial 911" line. The AI never writes this line.
  • Answers must cite their sources. Claude returns a structured answer that points to the exact bulletin passages it used. Our code then checks that each passage was found on this turn and comes from an official source. If any check fails, Soterra says "I don't know yet" and saves the question. Every answer ends with its source and time.
  • Hard limits in code. Soterra never confirms whether an exact address is inside an evacuation zone. It never calls a shelter open unless an official source says so.
  • Confidence from agreement. When separate agencies report the same thing, Soterra says so. Our code makes this call, not the model. Two feeds that come from the same upstream data count as one source.

After the call

  • Callbacks. If Soterra cannot answer, it saves the question as a follow-up for the caller's area. When a matching official update arrives, Convex calls the person back through Cartesia, and the call opens with the update.
  • Voicemail detection. If a callback reaches voicemail, Soterra leaves a short message and texts the details.
  • Texts. Callers can say "text me" or "text me every 2 hours." Texts are built only from bulletin fields, and callers can stop them one topic at a time. Landlines get calls instead of texts.

How we built it

Soterra has four main parts. A voice agent answers the phone. A backend holds every verified fact. An AI layer writes answers only from those facts. A pipeline collects information from official sources.

Voice (Cartesia)

The hotline runs on a Python agent built with Cartesia's Line SDK. Ink 2 turns the caller's speech into text, and Sonic 3.6 speaks the replies. The agent handles turn-taking and interruptions, and it says a short filler line like "One moment" when the backend is slow, so the line never goes silent. It reads the backend's reply word for word and adds nothing of its own. Callbacks go out through Cartesia's outbound-call API.

Backend (Convex)

Convex is our database and server in one. It stores every alert, source, call, and callback request. Each turn of a call is one round trip:

  1. Safety check. A mutation loads the caller's context and checks what they said for signs of immediate danger. A match returns the scripted 911 line right away.
  2. Search. A search-index query finds matching bulletins. We rank them by how well they match the question, where the caller is, how severe the situation is, and how recent the information is.
  3. Answer. Claude drafts a short reply from those bulletins.
  4. Save. A second mutation saves the reply, its sources, and any follow-ups in one atomic step.

Backend overhead before Claude runs is about 100 ms. If anything fails along the way, the caller hears a safe fallback message that includes 911. They never get silence or an error. Crons and scheduled functions run ingestion, callbacks, and scheduled texts.

AI (Claude)

Claude Haiku 5.5 answers live calls because it is fast. It returns structured output, and prompt caching cut our response time from 4.3 seconds to about 1 second. Every answer has to cite the passages it used, and our code checks those citations before anything is spoken. If nothing verified matches the question, Soterra says "I don't know yet" instead of guessing, and saves the question so it can call back.

Claude Sonnet 5.5 reads crawled agency pages and extracts facts. It may only return exact quotes, and code confirms that each quote really appears on the page before we store it.

Data (Apify and official feeds)

Direct adapters pull from the National Weather Service, USGS (earthquakes and volcanoes), OpenFEMA, the National Hurricane Center, Tsunami.gov, InciWeb, and NIFC. For agency pages with no API, Apify's Website Content Crawler and Cheerio Scraper do the work and report back to Convex by webhook. Only allowlisted official X accounts count as sources. Other posts are treated as signals and are never read to a caller. Any changed bulletin triggers matching callbacks.

Texts (Twilio and a Mac relay)

We send texts with the Twilio Messages API and signed webhooks. A Twilio trial account can only text verified numbers, so we also built a relay that sends texts through Messages on a Mac, using an iPhone. Rate limits keep anyone from being called or texted too often.

Companion app (iOS)

A SwiftUI app reads live alerts from Convex and has a button that calls the hotline. Convex search is the default.

Privacy

A phone number alone never unlocks personal information. We only share or change a caller's saved details after we verify who they are.

Testing

We wrote 595 TypeScript tests (Vitest) and 91 Python tests (pytest) for the voice agent. We also run simulated calls that play out full conversations from start to finish.

Built with: Cartesia (Line SDK, Ink 2, Sonic 3.6), Convex, Claude (Haiku 5.5, Sonnet 5.5), Apify, Twilio, TypeScript, Python, SwiftUI, Vitest, pytest


Challenges we ran into

  • Voice latency. Silence on a phone call makes people lose trust. Prompt caching cut Claude's response time from 4.3 seconds to under 1 second.
  • Answering machine traps. Early callback builds tried to deliver disaster updates to voicemail greetings, and then tried to answer the greeting itself. We added automatic answering machine detection so messages wait for a real person.
  • Text relay workarounds. Twilio trial accounts only text verified numbers, so we built an iPhone relay script to keep messaging working from start to finish.
  • Simulating disasters. You cannot schedule an earthquake for demo time. We built fake agency pages so we could test the whole ingestion pipeline on our own schedule.

Accomplishments that we're proud of

  • A working phone hotline. Anyone can pick up a phone right now and call +1 (712) 600-3362.
  • Answers checked by code. Every spoken answer is checked against the official sources we retrieved. If an answer cannot be cited, Soterra refuses to guess.
  • A fully automatic loop. When an official agency page updates, we ingest it, turn it into a bulletin, match it to waiting callers, and start an outgoing call within about 60 seconds.
  • Built for people left behind by technology. It works on flip phones, in low-signal areas, and for people who are not comfortable with apps.

What we learned

  • Government data is messy. Timestamp formats vary a lot, cancellations are often labeled as active alerts, and old publish dates clutter the feeds.
  • Keep facts separate from generation. We make Claude pull exact quotes only, and our code assembles the context. That way callers only hear statements we have verified.
  • Clear contracts help teams move fast. We set strict interfaces early, so four teammates could build the voice, pipeline, ingestion, and messaging parts at the same time without blocking each other.

What's next for Soterra

  • More languages. Soterra currently works in English only. We want to add support for other languages so more people can get help in the language they speak best.
  • More personal, targeted aid. We want Soterra to give help that fits each caller, such as guidance based on their location, their needs, and their situation, so the advice is more useful when it matters most.
  • Tools for dispatchers and first responders. We want to build features for emergency dispatchers and first responders, so they can share verified updates, see what callers are asking about, and respond faster.

Try it now: Call +1 (712) 600-3362

Built With

+ 4 more
Share this project:

Updates

posted an update —

Fun Fact: Did you know that Soterra combines soter (Greek for savior) and terra (Latin for earth)? So basically, it’s down-to-earth lifesaving info, right when you need to call for help!

LETS GO SOTERRA!!!

Log in or sign up for Devpost to join the conversation.

Submission history