> ## Documentation Index
> Fetch the complete documentation index at: https://www.datalegion.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js SDK

> Official Node.js SDK for the Data Legion API. Full TypeScript support with zero dependencies. Person and company enrichment, search, discovery, and utility endpoints.

The official Node.js SDK for the Data Legion API. Written in TypeScript with zero external dependencies.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install datalegion
  ```

  ```bash yarn theme={null}
  yarn add datalegion
  ```

  ```bash pnpm theme={null}
  pnpm add datalegion
  ```

  ```bash bun theme={null}
  bun add datalegion
  ```
</CodeGroup>

Requires Node.js 20+.

## Authentication

Get an API key by [signing up for free](https://www.datalegion.ai/sign-up); it's available in your dashboard after approval. The same key works across the API, SDKs, MCP server, and CLI.

<CodeGroup>
  ```typescript Environment variable theme={null}
  // Set DATALEGION_API_KEY in your environment
  import DataLegion from 'datalegion';
  const client = new DataLegion();
  ```

  ```typescript Direct theme={null}
  import DataLegion from 'datalegion';
  const client = new DataLegion({ apiKey: 'legion_...' });
  ```
</CodeGroup>

## Person

### Enrichment

Look up a person by email, phone, name, LinkedIn, or other identifiers.

```typescript theme={null}
import DataLegion from 'datalegion';

const client = new DataLegion({ apiKey: 'legion_...' });

const person = await client.person.enrich({
  email: 'jane.doe@example.com',
});

console.log(person.full_name);          // "Jane Doe"
console.log(person.job_title);          // "VP of Engineering"
console.log(person.company_name);       // "Acme Corp"
console.log(person.city, person.state); // "San Francisco" "California"
```

Return multiple matches with confidence scores by setting `multiple_results: true`.

```typescript theme={null}
const matches = await client.person.enrich({
  first_name: 'Jane',
  last_name: 'Doe',
  company: 'Acme',
  multiple_results: true,
  limit: 5,
  min_confidence: 'high',
});

console.log(`Found ${matches.total} matches`);
for (const match of matches.matches) {
  console.log(
    `${match.person.full_name} - ${match.match_metadata?.match_confidence}`
  );
}
```

### Search

Query people using a SQL `SELECT` against the `people` table. The query must start with `SELECT` and must not include a `LIMIT` clause — pass `limit` as a parameter.

```typescript theme={null}
const results = await client.person.search({
  query:
    "SELECT * FROM people WHERE job_title ILIKE '%engineer%' AND city = 'san francisco'",
  limit: 25,
});

// `total` reflects the full row count matching the WHERE clause across the
// database — useful for TAM / market-sizing — while `matches` is capped at `limit`.
console.log(`${results.matches.length} of ${results.total} total matches`);
for (const match of results.matches) {
  console.log(`${match.person.full_name} - ${match.person.job_title}`);
}
```

### Discovery

Find people using natural language.

```typescript theme={null}
const results = await client.person.discover({
  query: 'product managers at AI startups in New York',
  limit: 10,
});

// The generated SQL is included in the response (snake_case body field)
console.log(`Generated query: ${results.generated_query}`);

for (const match of results.matches) {
  console.log(`${match.person.full_name} at ${match.person.company_name}`);
}
```

## Company

### Enrichment

Look up a company by domain, name, ticker, or LinkedIn.

```typescript theme={null}
const company = await client.company.enrich({
  domain: 'google.com',
});

console.log(company.name);                         // CleanedRaw object
console.log(company.industry);                     // "Internet"
console.log(company.legion_employee_count);        // 182000
console.log(company.legion_employee_growth_rate);  // { "1m": 0.02, "3m": 0.05, ... }
```

### Search

Query companies using SQL.

```typescript theme={null}
const results = await client.company.search({
  query:
    "SELECT * FROM companies WHERE industry = 'software development' AND legion_employee_count > 50",
  limit: 20,
});

for (const match of results.matches) {
  console.log(`${match.company.name} - ${match.company.industry}`);
}
```

### Discovery

Find companies using natural language.

```typescript theme={null}
const results = await client.company.discover({
  query: 'fintech companies in London with over 200 employees',
  limit: 10,
});

for (const match of results.matches) {
  console.log(`${match.company.name} - ${match.company.legion_employee_count} employees`);
}
```

## Utility Endpoints

Utility endpoints are free and don't consume credits.

### Clean Fields

```typescript theme={null}
const cleaned = await client.utility.clean({
  fields: {
    email: '  JANE.DOE+work@GMAIL.COM  ',
    phone: '(555) 123-4567',
    domain: 'https://www.Google.com/about',
  },
});

for (const [field, result] of Object.entries(cleaned.results)) {
  console.log(`${field}: ${result.original} -> ${result.cleaned}`);
}
```

### Hash Email

```typescript theme={null}
const hashed = await client.utility.hashEmail({
  email: 'Jane.Doe+tag@gmail.com',
});

console.log(hashed.normalized_email);  // "janedoe@gmail.com"
console.log(hashed.hashes.sha256);     // SHA-256 hash
console.log(hashed.hashes.md5);        // MD5 hash
```

### Validate Data

```typescript theme={null}
const result = await client.utility.validate({
  email: 'not-an-email',
  phone: '+15551234567',
  company: 'Google',
});

if (!result.valid) {
  for (const err of result.errors) {
    console.log(`${err.field}: ${err.error}`);
  }
}
```

### Report a Data Issue

Found something wrong in a record? Report it against its `legion_id` — see [Report a Data Issue](/docs/api-reference/utility-report) for the `issue_type`/`issue_level` rules.

```typescript theme={null}
const report = await client.utility.reportPerson({
  legion_id: 'abc123',
  issue_type: 'incorrect',
  issue_level: 'field',
  field: 'job_title',
  observed_value: 'CEO',
  correct_value: 'CTO',
});

console.log(report.report_id, report.status); // e.g. 42 "new"
```

Company records use `client.utility.reportCompany()` with the same parameters.

## Response Metadata

After each request, response metadata is available on the client.

```typescript theme={null}
await client.person.enrich({ email: 'jane@example.com' });

console.log(client.requestId);           // Unique request ID
console.log(client.creditsUsed);         // Credits consumed
console.log(client.creditsRemaining);    // Remaining balance
console.log(client.rateLimitRemaining);  // Requests left in window
console.log(client.generatedQuery);      // SQL from discover endpoints
console.log(client.totalCountStatus);    // search/discover: "exact" | "estimate" | "page"
```

On `search`/`discover`, `totalCountStatus` tells you how the response `total` was derived: `"exact"` (true count), `"estimate"` (the query planner's row estimate — returned on broad queries where an exact count is too expensive, so treat it as a magnitude), or `"page"` (count unavailable; `total` is just the returned page size).

## Field Filtering

Control which fields are returned in the response.

```typescript theme={null}
// Only return specific fields
const person = await client.person.enrich({
  email: 'jane@example.com',
  include_fields: 'full_name,job_title,company_name,linkedin_url',
});

// Exclude fields
const person2 = await client.person.enrich({
  email: 'jane@example.com',
  exclude_fields: 'phones,locations,education',
});

// Require fields (skip records missing these)
const person3 = await client.person.enrich({
  email: 'jane@example.com',
  required_fields: 'work_email,mobile_phone',
});
```

## Error Handling

The SDK throws typed error classes for different error conditions.

```typescript theme={null}
import DataLegion, {
  AuthenticationError,
  InsufficientCreditsError,
  ValidationError,
  RateLimitError,
  DataLegionError,
} from 'datalegion';

const client = new DataLegion({ apiKey: 'legion_...' });

try {
  const person = await client.person.enrich({ email: 'jane@example.com' });
} catch (err) {
  if (err instanceof AuthenticationError) {
    // 401 - Invalid or missing API key
    console.error('Check your API key');
  } else if (err instanceof InsufficientCreditsError) {
    // 402 - Out of credits
    console.error(`Out of credits: ${err.message}`);
  } else if (err instanceof ValidationError) {
    // 422 - Invalid request parameters
    console.error(`Invalid input: ${JSON.stringify(err.details)}`);
  } else if (err instanceof RateLimitError) {
    // 429 - Rate limit exceeded
    console.error(`Rate limited, retry after ${client.retryAfter}s`);
  } else if (err instanceof DataLegionError) {
    // Other API errors
    console.error(`API error (${err.statusCode}): ${err.message}`);
  }
}
```

## Configuration

```typescript theme={null}
const client = new DataLegion({
  apiKey: 'legion_...',                     // Or set DATALEGION_API_KEY
  baseURL: 'https://api.datalegion.ai',          // Default
  timeout: 60000,                                // Milliseconds, default 60000
  defaultHeaders: {                              // Custom headers on all requests
    'X-Correlation-ID': 'my-request-123',
  },
});
```

## TypeScript

The SDK is written in TypeScript and exports all request and response types.

```typescript theme={null}
import DataLegion from 'datalegion';
import type {
  PersonResponse,
  PersonMatchesResponse,
  CompanyResponse,
  CompanyMatchesResponse,
  FieldCleanResponse,
  EmailHashResponse,
  ValidationResponse,
} from 'datalegion';

const client = new DataLegion({ apiKey: 'legion_...' });

// Return type is inferred based on multiple_results
const person: PersonResponse = await client.person.enrich({
  email: 'jane@example.com',
});

const matches: PersonMatchesResponse = await client.person.enrich({
  email: 'jane@example.com',
  multiple_results: true,
});
```

## Resources

* [npm Package](https://www.npmjs.com/package/datalegion)
* [API Reference](/docs/api-reference/overview)
