Campaign Weather — Devpost Entry

Inspiration

Election coverage can feel like trying to understand a storm by looking through three different windows. People see political ads, news stories, and search trends, but those signals are scattered across the web and are easy to misunderstand.

We built Campaign Weather to put those public signals in one place without pretending they predict an election. A voter should be able to quickly see what is happening around a race and follow the evidence back to the original source. A journalist should be able to check what changed, when it changed, and where the information came from.

Our first demo follows the 2026 Wisconsin governor race between Tom Tiffany and David Crowley.

What it does

Campaign Weather is a nonpartisan, public evidence dashboard for election coverage. It has three separate signal layers:

  • Public ad activity: Political ads that were publicly observed, plus available date, view, and spending ranges.
  • News context: Recent news results that are specifically connected to the race.
  • Search attention: Relative Google search interest for the candidates in a shared Google Trends request.

It never combines these layers into a score, a poll, or a prediction. Seeing more ads or searches does not mean a candidate is winning or that voters support them.

The Voter Radar gives people a quick view of the race. An Ad Passport lets them inspect one ad record and open its public source. The Press Desk is the deeper evidence view for journalists: it shows newly observed ads, source links, capture times, query details, and the rules used to flag a change.

Campaign Weather also includes an AI Evidence Investigator. It can write a short, neutral summary of a supported change using only records already saved by the platform. It cites those records and clearly says what the data cannot prove. It refuses questions that ask for political advice, predictions, candidate rankings, or claims about voter opinion.

How we built it

We built the public experience with Next.js and TypeScript, and used Convex as the backend and database. Convex stores a snapshot of each successful data pull, so the site can show the most recent reliable information instead of making visitors wait on a live search.

SerpApi runs only on the server. That keeps our API key out of the browser. We save the original response for auditing, then turn it into smaller, safe records for the app to display. The app records the source, query, capture time, and limits of every visible result.

We used these SerpApi APIs in Campaign Weather:

SerpApi API What it does in Campaign Weather
Google Ads Transparency Center API Looks up publicly available political-ad records for verified campaign advertisers. We use it to show creative format, public source links, first and last observed dates, and available view and spending ranges.
Google News API Finds recent news coverage using a race-specific search for both candidates. Those results provide context, not proof that an ad caused something or that voters feel a certain way.
Google Trends API Gets one shared, Wisconsin-only time series for both candidates over the last three months. It shows relative search interest only, and we keep the terms together so the comparison is fair.
SerpApi Account API Checks how many searches are left before a refresh. Campaign Weather blocks a refresh if it would go below a safety reserve, helping us control cost and avoid accidental overuse.

For the AI Evidence Investigator, we use gpt-5-mini with a strict response format. The model receives only selected stored evidence, not open internet access. Its answer must point back to stored records, and the app rejects citations that are outside the selected evidence.

Challenges we ran into

The hardest challenge was making the product useful without overstating what the data means. Political data can sound more certain than it really is. For example, an ad's available spending range is not an exact total, and Google Trends is not a poll.

We solved this by separating ads, news, and search attention instead of blending them into one "heat" score. We also use careful words like "newly observed" and "relative search interest," and show a limitation next to each layer.

Another challenge was handling missing or incomplete live data. One SerpApi result can fail or return fewer fields than another. Each source refreshes independently, the app keeps the latest successful snapshot, and an unavailable layer is labeled honestly instead of being treated as zero activity.

Finally, live API calls cost money. We built a server-side budget check, a fixed refresh cost, and a search reserve so the demo cannot silently spend through the account.

Accomplishments that we're proud of

  • We turned live public campaign information into an experience that is easy to understand without reducing it to a prediction.
  • We made every major signal traceable: users can see its source, query, capture time, and limitations.
  • We built a real change-detection system that can flag newly observed ads or changes in publicly available ad details between captures.
  • We kept the experience anonymous and browse-only: Campaign Weather does not ask voters to create an account or share political preferences.
  • We made the AI useful but bounded. It explains evidence; it does not tell people how to vote.
  • We added cost and safety controls around live SerpApi refreshes instead of treating API calls as unlimited.

What we learned

We learned that trust comes from showing the instruments, not just the conclusion. A clean dashboard is helpful, but people need to know where the information came from and what it cannot tell them.

We also learned that different public signals answer different questions. Ads show public campaign activity. News gives reporting context. Trends shows relative search interest. None of them, alone or together, tells us who will win.

Building with live data also taught us to plan for failure. A good civic tool should still be honest and useful when one source is delayed, incomplete, or unavailable.

What's next for Campaign Weather

Next, we want to expand from the Wisconsin governor race to more 2026 governor and Senate races. We also want to add stronger Press Desk filters, clearer evidence exports, and a wider set of verified campaign and advertiser records.

We plan to keep improving the change timeline so journalists can compare snapshots more easily over time. Before any broader launch, we will add more source verification, refresh controls, and accessibility testing.

Most importantly, we want to keep Campaign Weather focused on its core promise: help people inspect public election signals without turning them into a forecast, a persuasion tool, or a substitute for reporting.

Built With

  • convex
  • nextjs
  • openai
  • serpapi
Share this project:

Updates

Submission history