| title | Smart Spreadsheet |
|---|---|
| sidebarTitle | Smart Spreadsheet |
| description | An AI-powered company enrichment tool that uses Exa search and Claude to extract verified company data with source attribution. |
import RealtimeLearnMore from "/snippets/realtime-learn-more.mdx";
Smart Spreadsheet is an AI-powered tool that enriches company data on demand. Input a company name or website URL and get verified information including industry, headcount, and funding details; each with source attribution. Results appear in the frontend in real-time as each task completes.
- A Next.js app with Trigger.dev for background tasks
- Exa – an AI-native search engine that returns clean, structured content ready for LLM extraction
- Claude via the Vercel AI SDK for data extraction
- Supabase PostgreSQL database for persistence
- Trigger.dev Realtime for live updates to the frontend
<video controls className="w-full aspect-video" src="https://content.trigger.dev/smart-spreadsheet.mp4"
<Card title="View the Smart Spreadsheet repo" icon="github" href="https://github.com/triggerdotdev/examples/tree/main/smart-spreadsheet"
Click here to view the full code for this project in our examples repository on GitHub. You can fork it and use it as a starting point for your own project.
The enrichment workflow:
- Trigger enrichment – User enters a company name or URL in the spreadsheet UI
- Parallel data gathering – Four subtasks run concurrently to fetch basic info, industry, employee count, and funding details
- AI extraction – Each subtask uses Exa search + Claude to extract structured data with source URLs
- Real-time updates – Results appear in the frontend as each subtask completes
- Persist results – Enriched data is saved to Supabase with source attribution
- Parallel processing – All four enrichment categories run simultaneously using batch.triggerByTaskAndWait
- Source attribution – Every data point includes the URL it was extracted from
- Live updates – Results appear in the UI as each task completes using Realtime
- Structured extraction – Zod schemas ensure consistent data output from Claude
The main task triggers all four enrichment subtasks simultaneously using batch.triggerByTaskAndWait:
const { runs } = await batch.triggerByTaskAndWait([
{ task: getBasicInfo, payload: { companyName, companyUrl } },
{ task: getIndustry, payload: { companyName, companyUrl } },
{ task: getEmployeeCount, payload: { companyName, companyUrl } },
{ task: getFundingRound, payload: { companyName, companyUrl } },
]);Each subtask uses metadata.parent.set() to update the parent's metadata as soon as data is extracted:
// After Claude extracts the data, update the parent task's metadata
metadata.parent.set("website", object.website);
metadata.parent.set("description", object.description);The frontend subscribes to these metadata updates using Realtime, so users see each field populate as it's discovered.
| File | Description |
|---|---|
src/trigger/enrich-company.ts |
Main orchestrator that triggers parallel subtasks and persists results |
src/trigger/get-basic-info.ts |
Extracts company website and description |
src/trigger/get-industry.ts |
Classifies company industry |
src/trigger/get-employee-count.ts |
Finds employee headcount |
src/trigger/get-funding-round.ts |
Discovers latest funding information |