Inspiration
Every year, San Francisco has thousands of people who want to volunteer and dozens of nonprofits desperate for help and the two rarely find each other efficiently. A generic volunteer directory puts all the work on the person: read fifty listings, guess which skills matter, guess what's actually urgent this week. Most people give up before they ever help anyone. We wanted to flip that: instead of asking a volunteer to do the matching, let AI do it, and ground the recommendation in what the city actually needs right now, not a static list from last year.
What it does
A volunteer uploads a resume and tells us what they care about and how much time they have. AI reads that resume and builds a short skills profile in seconds. We then score every opportunity against that profile skills, causes, availability, and neighborhood fit and layer in a live signal from San Francisco's public 311 data to catch where community need is spiking (a cold-snap simulation shows this dramatically: recommendations visibly re-rank toward shelter and food-security roles when we simulate a surge). For the top three matches, AI writes a short, specific, always-encouraging explanation of why that opportunity is worth their time. The result: three concrete next steps instead of an overwhelming list, each with a reason, a location on a map, and a direct link to the organization.
How we built it
- Frontend: React, TypeScript, Vite, Tailwind CSS, Framer Motion for the reveal/ re-rank animations, and Leaflet for an interactive map of every matched opportunity.
- Backend: Python, FastAPI, pydantic. A pure, unit-tested scoring function combines skill/cause/availability overlap with a live urgency signal.
- AI: DigitalOcean Gradient AI serverless inference (Meta's Llama 4 Maverick) does the real work twice per session turning a resume into a structured profile, and writing the three personalized match explanations in a single batched call. Every AI call is hardened with retries and a deterministic fallback so a slow or failed AI response never breaks the demo.
- Live data: SF's public 311 API (DataSF/Socrata), aggregated and cached, drives the community-urgency scoring and the cold-snap re-ranking demo.
- Deployment: Docker + DigitalOcean App Platform.
Challenges we ran into
Real-world resumes are messy PDF text extraction can collapse a whole header (name, email, phone) into one garbled line with no line breaks. We had to make name/skill extraction robust to that instead of assuming clean formatting. We also hit real latency variance from different AI models before landing on one that was both fast and accurate enough for a live demo. And we caught a subtle but important bug: our first prompt let the AI tell a volunteer "you're not the best fit" for a lower-ranked match we rewrote it to always find a genuine, constructive connection instead.
Accomplishments that we're proud of
A fully working, tested, end-to-end flow real resume in, real AI-driven profile and explanations out, live city data changing the ranking in front of your eyes verified through the actual UI, not just API calls.
What we learned
Grounding AI output in real, live public data makes the "why" behind a recommendation far more convincing than a black-box score ever could and building a solid deterministic fallback for every AI call is what makes a live AI demo actually safe to run in front of judges.
What's next for Tenderly
Real nonprofit partnerships and verified opportunity listings, a conversational assistant for browsing needs by neighborhood, and expanding the live-data signal beyond 311 to include shelter capacity and food-bank demand directly.
Built With
- datasf
- digitalocean
- digitalocean-app-platform
- digitalocean-gradient-ai
- docker
- fastapi
- framer-motion
- httpx
- leaflet.js
- llama-4-maverick
- openai-sdk
- pydantic
- pypdf
- pytest
- python
- react
- socrata-api
- tailwindcss
- typescript
- uvicorn
- vite
Log in or sign up for Devpost to join the conversation.