Granted — Project Overview
Inspiration
The idea came from a simple, frustrating observation: early-stage founders, students, and small nonprofits rarely lose out on grant funding because their idea is weak — they lose out because the process itself is a maze. Eligibility requirements are buried in dense PDFs, deadlines are scattered across a dozen different government pages, and there's no way to know what you actually qualify for until you've already sunk hours into a full application. We wanted to turn "I have an idea but no clue how to get it funded" into a matched, demystified funding path — something that feels like a conversation with a knowledgeable advisor, not a bureaucratic form. That problem, and the fact that grants.gov and SBIR.gov both offer free, live, no-signup data feeds, made it a natural fit for a same-day build at FireHacks 2026 (Zoho HQ, Pleasanton) under the AI and Research tracks.
What it does
Granted is a conversational AI grants advisor. You describe your project, team, and funding needs in plain language, and it matches you against live funding opportunities pulled simultaneously from grants.gov, SBIR.gov, and open web search — then checks your actual eligibility against each grant's real requirements rather than just returning a list of titles. Instead of a one-shot verdict, it runs a genuine eligibility interview: if something about your fit is unclear, it asks a targeted follow-up question before committing to a "qualifies / likely / unclear / no" verdict, and it explains exactly what to do next in plain language. Since the hackathon, it's grown a Phase 2 capability too: for a given grant, it can go find and actually read the real NOFO/RFP PDF via live web search and return a clean checklist of required documents and application steps — not a guessed list, but one grounded in the document it found.
How we built it
The backend is Python/FastAPI with Uvicorn, talking to grants.gov and SBIR.gov over async HTTP (httpx), with Pydantic schemas keeping every request and response typed. The frontend is React on Vite, split into a landing page and a /chat route via react-router. Both are built and deployed as a single Render web service, with FastAPI serving the compiled React app directly — one service, no extra infrastructure. For the AI layer we use OpenAI's Responses API (via an Azure AI Foundry endpoint) with forced structured tool-calls for every decision the model makes, so nothing is left to free-text parsing: a router call decides each turn's intent, a matching call ranks and explains candidates against the user's real profile, and an interview call either asks a question or gives a verdict — every one of them returns typed JSON with explicit fields like qualifies and confidence. We built it in phases with no phase started without an explicit go-ahead: scaffold first, then grant matching, then a UI polish pass, then a full rework from a structured form into a real conversation once it became clear users shouldn't have to volunteer structured data, then a visual identity pass, then live web search (pulled forward from a later phase), and finally the PDF-based document checklist.
Challenges we ran into
A few things bit us along the way. Midway through swapping AI providers, we discovered the API key we'd been handed wasn't a standard OpenAI key at all — it was an Azure AI Foundry key that needed the Responses API and a custom base URL, which took systematic trial-and-error against different endpoint shapes to diagnose. SBIR.gov's integration originally pointed at the awards endpoint (historical, already-funded data) instead of open solicitations — a real bug, since you can't apply to something that's already been awarded — and separately, that same API has been genuinely flaky and rate-limited throughout the build, so we had to make the whole pipeline degrade gracefully instead of erroring out. On the AI side, live testing caught the model confidently returning a "no" verdict based on just a grant's title, despite being told its eligibility text wasn't available — a real trust violation that we fixed with a code-level guardrail that force-downgrades confidence whenever source text can't be fetched, rather than trusting the model's own self-assessment. We also found the smaller model couldn't reliably infer which grant an eligibility interview was continuing about from conversation history alone, so we made the client track the active grant explicitly instead. Most recently, we're chasing a chat-freezing bug: the browser console shows repeated React "duplicate key" warnings for the same web-search grant URL appearing twice in one matches array, which needs root-causing upstream in the web search service rather than just patched over.
Accomplishments that we're proud of
We shipped and live-tested — with real AI calls, never mocked — a full conversational matching pipeline across three parallel live data sources, plus a genuine eligibility interview experience rather than a one-shot form. The data-integrity guardrail is something we're especially proud of: the "never fabricate, never guess" requirement isn't just a prompt instruction, it's enforced in code, and we caught and fixed a real violation of it during testing instead of assuming the prompt was enough. We also pulled a stretch-goal feature (live web search) forward into the core experience, and went further post-hackathon by shipping Phase 2 — reading actual grant PDFs to produce a real, sourced document checklist instead of a plausible-sounding guess.
What we learned
The biggest lesson was that testing end-to-end with real AI calls, every time, is non-negotiable — every one of our worst bugs (the false-confidence verdict, the interview-continuation failure) only showed up under live conditions and would have shipped invisibly under mocked tests. We also learned that trusting an LLM's self-reported confidence is risky by default; if a requirement really matters, it has to be enforced with a code-level check, not just requested in a prompt. And we learned to be skeptical of assumptions about infrastructure — "it's an OpenAI key" turned out to be wrong, "SBIR awards are gettable" turned out to be wrong — the fix in both cases was going back to first principles and testing the actual endpoint rather than trusting the label on the tin.
What's next for Granted
The most immediate priority is finishing the root-cause on the active chat-freeze bug — deduping web-search grant URLs at the source rather than downstream. After that, Phase 4 (an actual tested deployment to Render — the config exists but has never been run for real) is next, and the original Phase 3 scope (plain-language RFP summaries, NSF/USAspending context) is being reconsidered since live web search already covers most of what it was meant to solve. Longer-term, the natural next steps are letting users save matches and track deadlines over time, expanding beyond federal sources into state and foundation grants, and eventually offering AI-assisted help drafting the actual application narrative — not just finding and explaining the grant, but helping write the thing.
Log in or sign up for Devpost to join the conversation.