---
title: "Lead Enrichment"
description: "Classify and prioritize sales leads in a single nua.list() call."
canonical: "https://nuabase.com/docs/examples/lead-enrichment/"
---

> Documentation index: https://nuabase.com/llms.txt

This example enriches sales leads with classification and prioritization, in a single `nua.list()` call.

## Problem

You have a list of sales leads with notes from various sources (forms, meetings, referrals). You need to:

1. Classify leads by company size and type
2. Assign priority based on purchase intent
3. Recommend next steps for each lead

## Solution

```typescript
import { Nua, z } from 'nuabase';
import { findLocalAgent } from 'nuabase/local-agent';

const nua = Nua.direct({ localAgent: await findLocalAgent() });

// Define the enrichment schema
const EnrichmentSchema = z.object({
  companySize: z.enum(['solo', 'small', 'medium', 'enterprise']),
  companyType: z.enum(['startup', 'agency', 'saas', 'ecommerce', 'enterprise', 'other']),
  priority: z.enum(['low', 'medium', 'high', 'urgent']),
  purchaseIntent: z.enum(['exploring', 'evaluating', 'ready-to-buy']),
  recommendedPlan: z.string(),
  nextStep: z.string(),
});

// Sample leads data
const leads = [
  {
    id: 'lead-001',
    name: 'Sarah Chen',
    email: 'sarah@acmecorp.com',
    notes: 'CEO at Acme Corp (500+ employees). Looking for enterprise solution. Budget approved for Q1. Wants demo next week.'
  },
  {
    id: 'lead-002',
    name: 'Mike Johnson',
    email: 'mike@freelancedev.io',
    notes: 'Freelance developer. Curious about the product. Checking pricing page frequently. No timeline mentioned.'
  },
  {
    id: 'lead-003',
    name: 'Lisa Park',
    email: 'lisa@growthstartup.co',
    notes: 'Head of Engineering at a Series A startup (30 people). Evaluating tools for their engineering team. Decision in 2 weeks.'
  },
  {
    id: 'lead-004',
    name: 'Tom Williams',
    email: 'tom@bigagency.com',
    notes: 'Digital agency with 150 employees. Managing 50+ client projects. Current tool is too slow. Urgent need.'
  }
];

// Enrich all leads
async function enrichLeads() {
  const result = await nua.list(
    `You are a sales analyst for a B2B SaaS company.

Analyze each lead and provide:
- Company size based on context clues
- Type of company/organization
- Priority (urgent = ready to buy now, high = strong intent, medium = actively evaluating, low = just browsing)
- Purchase intent level
- Recommended plan tier
- Specific next step for the sales team`,
    {
      input: leads,
      primaryKey: 'id',
      output: { name: 'enrichment', schema: EnrichmentSchema }
    }
  );

  if (!result.success) {
    console.error('Enrichment failed:', result.error);
    return;
  }

  // Display results
  console.log('Lead Enrichment Results\n');
  console.log('='.repeat(60));

  // Rows may come back in any order, so look each one up by its primary key
  const leadsById = new Map(leads.map(l => [l.id, l]));

  for (const row of result.data) {
    const lead = leadsById.get(row.id)!;
    const e = row.enrichment;

    console.log(`\n${lead.name} (${lead.email})`);
    console.log(`  Company: ${e.companySize} ${e.companyType}`);
    console.log(`  Priority: ${e.priority.toUpperCase()}`);
    console.log(`  Intent: ${e.purchaseIntent}`);
    console.log(`  Recommended: ${e.recommendedPlan}`);
    console.log(`  Next Step: ${e.nextStep}`);
  }

  // Show usage stats
  console.log('\n' + '='.repeat(60));
  console.log(`Tokens used: ${result.usage.totalTokens}`);
  console.log(`Latency: ${result.latencyMs}ms`);
  console.log(`Model: ${result.model}`);
}

enrichLeads();
```

## Output

From a run on Claude Code, with the default logger's `[INFO]` lines left out. The wording of free-text fields such as the next step varies from run to run:

```text
Lead Enrichment Results

============================================================

Sarah Chen (sarah@acmecorp.com)
  Company: enterprise enterprise
  Priority: URGENT
  Intent: ready-to-buy
  Recommended: Enterprise
  Next Step: Schedule a tailored executive demo for next week with Sarah and key stakeholders; prepare an enterprise proposal and pricing aligned to the approved Q1 budget.

Mike Johnson (mike@freelancedev.io)
  Company: solo other
  Priority: LOW
  Intent: exploring
  Recommended: Free / Starter
  Next Step: Enroll in an automated nurture sequence with a free trial or starter plan offer, plus a limited-time discount to convert pricing-page interest.

Lisa Park (lisa@growthstartup.co)
  Company: small startup
  Priority: HIGH
  Intent: evaluating
  Recommended: Team / Growth
  Next Step: Book a technical demo with Lisa this week, offer a team trial for the engineering org, and share startup pricing and comparison materials before the 2-week decision deadline.

Tom Williams (tom@bigagency.com)
  Company: medium agency
  Priority: URGENT
  Intent: ready-to-buy
  Recommended: Business / Agency (multi-client)
  Next Step: Call Tom within 24 hours to show performance and multi-client project management, then offer a quick-start migration plan from the current tool and an agency pricing proposal.

============================================================
Tokens used: 3272
Latency: 6663ms
Model: claude-code:claude-opus-5-5
```

## Processing Many Leads

All rows go into one request. For hundreds of leads, split them into chunks and keep the prompt the same for every chunk, so the provider can reuse its cached copy of the prompt and schema:

```typescript
const prompt = `You are a sales analyst for a B2B SaaS company. ...`;
const output = { name: 'enrichment', schema: EnrichmentSchema };

for (let i = 0; i < allLeads.length; i += 50) {
  const result = await nua.list(prompt, {
    input: allLeads.slice(i, i + 50),
    primaryKey: 'id',
    output,
  });
  // ...
}
```

## Variations

### Add Scoring

```typescript
const ScoredLeadSchema = z.object({
  score: z.number().min(0).max(100),
  priority: z.enum(['low', 'medium', 'high', 'urgent']),
  factors: z.array(z.object({
    factor: z.string(),
    impact: z.enum(['positive', 'negative']),
  })).max(3),
});
```

### Industry Classification

```typescript
const IndustrySchema = z.object({
  industry: z.enum([
    'technology', 'healthcare', 'finance', 'retail',
    'manufacturing', 'education', 'other'
  ]),
  subIndustry: z.string().optional(),
  relevantProducts: z.array(z.string()).max(3),
});
```

### Multi-Language Support

```typescript
const result = await nua.list(
  `Analyze the leads. Respond in English regardless of the input language.`,
  { input: internationalLeads, primaryKey: 'id', output }
);
```
