Parallel Company Enrichment
Overview
Data Enrichment with Supabase + Parallel
Build a real-time data enrichment pipeline using Supabase Edge Functions and Parallel's Task API.
This cookbook demonstrates how to create a data enrichment experience where users input minimal data (e.g., company names) and get back enriched information automatically.

Why Supabase + Parallel?
| Feature | Benefit |
|---|---|
| Zero infrastructure | Supabase Edge Functions + Parallel = no servers to manage |
| Real-time updates | Supabase Realtime pushes enrichment results to the UI instantly |
| Flexible schema | JSONB storage adapts to any enrichment fields without migrations |
| Cost-effective | Pay only for what you use on both platforms |
| Global edge | Edge Functions run close to users, Parallel handles web research |
Architecture
_16┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐_16│ Web App │────▶│ API Routes │────▶│ Edge Function │────▶│ Parallel API │_16│ (Next.js) │ │ (Next.js) │ │ (Supabase) │◀────│ (Task API) │_16└─────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘_16 │ │ │ │_16 │ realtime │ secret key │ writes │ researches_16 ▼ ▼ ▼ ▼_16┌─────────────────────────────────────────────────────────────────────────────────────┐_16│ Supabase Database │_16│ ┌─────────────┐ ┌──────────────────────────────────────┐ │_16│ │ companies │ │ enrichment fields (JSONB) │ │_16│ │ - name │ │ - industry, funding, employees... │ │_16│ │ - website │ │ - custom fields you define │ │_16│ │ - status │ │ │ │_16│ └─────────────┘ └──────────────────────────────────────┘ │_16└─────────────────────────────────────────────────────────────────────────────────────┘
How It Works
- User submits a company name (and optional website)
- Frontend inserts a record with
status: pending - Frontend calls a Next.js API route
- API route invokes the Edge Function using the secret key (server-side)
- Edge Function calls Parallel's Task API with a structured output schema
- Parallel searches the web and returns structured data
- Edge Function saves results to the database
- Supabase Realtime pushes the update to the frontend
- UI updates automatically with enriched data
Quick Start
Prerequisites
- Check out the code for the cookbook
- Supabase CLI installed
- A Supabase project (free tier works)
- A Parallel API key
- Node.js 18+
1. Clone and Set Up
_10# Navigate to the cookbook_10cd typescript-recipes/parallel-supabase-enrichment_10_10# Link to your Supabase project (config.toml is already provided)_10# Find your project ref in: Dashboard > Project Settings > General > Reference ID_10# Or from your project URL: https://supabase.com/dashboard/project/<project-ref>_10supabase link --project-ref your-project-ref
2. Create the Database Tables
Run the SQL files in your Supabase SQL Editor (Dashboard > SQL Editor > New Query):
- Copy and run
sql/01_create_companies.sql(required) - Copy and run
sql/02_create_enrichment_columns.sql(optional - for dynamic columns)
3. Set Up Secrets
_10# Set your Parallel API key as a secret_10supabase secrets set PARALLEL_API_KEY=your-parallel-api-key
4. Deploy Edge Functions
_10supabase functions deploy enrich-company_10supabase functions deploy poll-enrichment
5. Set Up the Web App
_10cd web_10_10# Install dependencies_10npm install_10_10# Create environment file_10cp .env.example .env.local
Edit .env.local with your Supabase credentials (Dashboard > Project Settings):
_10# From Data API > Project URL_10NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co_10# From API Keys > publishable key (client-side)_10NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-key_10# From API Keys > secret key (server-side only)_10SUPABASE_SECRET_KEY=your-secret-key
6. Run the App
_10npm run dev
Open http://localhost:3000 and start enriching!
Project Structure
_24parallel-supabase-enrichment/_24├── README.md # This file_24├── sql/_24│ ├── 01_create_companies.sql # Main table with enrichment tracking_24│ └── 02_create_enrichment_columns.sql # (Optional) Dynamic column config_24├── supabase/_24│ ├── config.toml # Supabase configuration_24│ └── functions/_24│ ├── enrich-company/ # Main enrichment function_24│ │ └── index.ts_24│ └── poll-enrichment/ # Background polling for long tasks_24│ └── index.ts_24└── web/ # Next.js frontend_24 ├── app/_24 │ ├── api/_24 │ │ ├── enrich/route.ts # API route to call enrich-company_24 │ │ └── poll/route.ts # API route to call poll-enrichment_24 │ ├── layout.tsx_24 │ ├── page.tsx # Main UI_24 │ └── globals.css_24 ├── lib/_24 │ └── supabase.ts # Supabase client + types_24 ├── package.json_24 └── .env.example
Customizing Enrichment Fields
The enrichment schema is defined in the Edge Function. To change what data gets enriched:
Important: When you modify
outputSchemain the Edge Function, also updateENRICHMENT_FIELDSinweb/lib/supabase.tsto display the new columns in the table.
Option 1: Static Schema (Simpler)
Edit supabase/functions/enrich-company/index.ts:
_16const outputSchema = {_16 type: "object",_16 properties: {_16 industry: { type: "string", description: "Primary industry" },_16 employee_count: {_16 type: "string",_16 enum: ["1-10", "11-50", "51-200", "201-500", "500+"],_16 description: "Company size range"_16 },_16 headquarters: { type: "string", description: "HQ location (City, Country)" },_16 // Add your custom fields here_16 ceo_name: { type: "string", description: "Current CEO or founder name" },_16 tech_stack: { type: "string", description: "Primary technologies used" },_16 },_16 required: ["industry", "employee_count", "headquarters"],_16};
Option 2: Dynamic Schema (Advanced)
Use the enrichment_columns table to define fields in the database:
_10INSERT INTO enrichment_columns (name, display_name, column_type, description)_10VALUES ('ceo_name', 'CEO Name', 'text', 'The current CEO or chief executive');
The Edge Function will automatically build the schema from these definitions.
Configuration
Parallel Processors
The Edge Function uses base-fast by default. See processor options and pricing to choose the right one for your use case.
_10const taskRun = await parallel.taskRun.create({_10 processor: "base", // Change processor here_10 // ..._10});
Environment Variables
Edge Functions (set via supabase secrets set):
PARALLEL_API_KEY- Your Parallel API key
Web App (in .env.local):
NEXT_PUBLIC_SUPABASE_URL- Your Supabase project URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY- Client-side key for database/realtimeSUPABASE_SECRET_KEY- Server-side key for calling Edge Functions (never expose to browser)
Handling Long-Running Tasks
The Parallel Task API may take longer than the Edge Function timeout (50s) for complex enrichments. This cookbook handles that with a polling pattern:
enrich-companystarts the task and stores therun_id- If the task doesn't complete in time, it returns with
status: processing poll-enrichmentruns periodically to check pending tasks- The frontend polls via API route (
/api/poll) every 10 seconds
For production, consider using Supabase Cron to run poll-enrichment automatically instead of client-side polling.
Troubleshooting
"PARALLEL_API_KEY not configured"
_10supabase secrets set PARALLEL_API_KEY=your-key_10# Redeploy the function_10supabase functions deploy enrich-company
Enrichment stuck on "processing"
Check Edge Function logs in the Supabase Dashboard (Edge Functions > enrich-company > Logs).
Or trigger a manual poll:
_10curl -X POST https://your-project.supabase.co/functions/v1/poll-enrichment \_10 -H "Authorization: Bearer your-secret-key"
Real-time updates not working
Ensure the table has realtime enabled:
_10ALTER PUBLICATION supabase_realtime ADD TABLE companies;
Resources
- Parallel API Documentation
- Parallel Task API Quickstart
- Supabase Edge Functions Guide
- Supabase Realtime
- parallel-web npm package
License
MIT...
Details
Third-party integrations and docs are managed by Supabase partners.

