Skip to content

TypeScript

TypeScript Examples

Complete TypeScript examples for integrating with the OpenProspect API using native fetch and popular HTTP clients.

Installation

Using Native Fetch (Node.js 18+)

No installation needed - fetch is built into Node.js 18+.

Using Axios

Bash
npm install axios dotenv
npm install --save-dev @types/node

Setup

Environment Variables

Create a .env file:

Bash
# .env
OPENPROSPECT_API_KEY=lnc_live_your_api_key_here
PROSPECT_SEARCH_ID=550e8400-e29b-41d4-a716-446655440000

Type Definitions

TypeScript
// types.ts

export interface Company {
  id: string;
  prospect_search_id: string;
  name: string;
  city?: string;
  country?: string;
  business_type?: string;
  website?: string;
  match_score: number;
  review_status: "accepted" | "rejected" | "pending";
  phone?: string;
  contacts: Contact[];
  created_at: string;
  updated_at: string;
}

export interface Contact {
  id: string;
  name: string;
  title?: string;
  email?: string;
  linkedin_url?: string;
}

export interface CompanyListResponse {
  items: Company[];
  total: number;
  limit: number;
  offset: number;
  has_more: boolean;
}

export interface Job {
  id: string;
  title: string;
  platform: string;
  date_posted: string;
  job_url: string;
}

export interface CompanyJobsResponse {
  jobs: Job[];
  total: number;
  limit: number;
  offset: number;
  has_more: boolean;
  activity_strength: "STRONG" | "MODERATE" | "LIGHT" | "NONE";
  velocity_per_month: number;
}

export interface Technology {
  name: string;
  category: string;
  confidence: number;
  version?: string;
}

export interface WebTechDetailsResponse {
  technologies: Technology[];
  total: number;
  limit: number;
  offset: number;
  has_more: boolean;
  scan_successful: boolean;
  status: string;
}

export interface ApiError {
  error: string;
  message: string;
}

API Client Class (Fetch)

TypeScript
// openprospect-client.ts

import * as dotenv from "dotenv";
import { Company, CompanyListResponse, CompanyJobsResponse, WebTechDetailsResponse } from "./types";

dotenv.config();

export class OpenProspectClient {
  private apiKey: string;
  private baseUrl: string;

  constructor(apiKey: string, baseUrl: string = "https://api.openprospect.io") {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.baseUrl}${endpoint}`;
    const response = await fetch(url, {
      ...options,
      headers: {
        "Authorization": `Bearer ${this.apiKey}`,
        "Accept": "application/json",
        "Content-Type": "application/json",
        ...options.headers,
      },
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`API Error: ${error.message || response.statusText}`);
    }

    return response.json();
  }

  async listCompanies(params: {
    prospectSearchId: string;
    limit?: number;
    offset?: number;
    minMatchScore?: number;
    reviewStatus?: "accepted" | "rejected" | "pending" | "all";
    search?: string;
  }): Promise<CompanyListResponse> {
    const searchParams = new URLSearchParams({
      prospect_search_id: params.prospectSearchId,
      limit: params.limit?.toString() || "50",
      offset: params.offset?.toString() || "0",
    });

    if (params.minMatchScore !== undefined) {
      searchParams.set("min_match_score", params.minMatchScore.toString());
    }
    if (params.reviewStatus) {
      searchParams.set("review_status", params.reviewStatus);
    }
    if (params.search) {
      searchParams.set("search", params.search);
    }

    return this.request<CompanyListResponse>(
      `/api/v1/companies/?${searchParams}`
    );
  }

  async getCompany(companyId: string): Promise<Company> {
    return this.request<Company>(`/api/v1/companies/${companyId}`);
  }

  async getCompanyJobs(params: {
    companyId: string;
    daysBack?: number;
    platform?: string;
    limit?: number;
    offset?: number;
  }): Promise<CompanyJobsResponse> {
    const searchParams = new URLSearchParams({
      days_back: params.daysBack?.toString() || "30",
      limit: params.limit?.toString() || "50",
      offset: params.offset?.toString() || "0",
    });

    if (params.platform) {
      searchParams.set("platform", params.platform);
    }

    return this.request<CompanyJobsResponse>(
      `/api/v1/companies/${params.companyId}/jobs?${searchParams}`
    );
  }

  async getCompanyWebTech(params: {
    companyId: string;
    category?: string;
    minConfidence?: number;
    limit?: number;
    offset?: number;
  }): Promise<WebTechDetailsResponse> {
    const searchParams = new URLSearchParams({
      min_confidence: params.minConfidence?.toString() || "0",
      limit: params.limit?.toString() || "100",
      offset: params.offset?.toString() || "0",
    });

    if (params.category) {
      searchParams.set("category", params.category);
    }

    return this.request<WebTechDetailsResponse>(
      `/api/v1/companies/${params.companyId}/webtech-intel?${searchParams}`
    );
  }
}

Basic Examples

List Companies

TypeScript
// examples/list-companies.ts

import { OpenProspectClient } from "../openprospect-client";

const apiKey = process.env.OPENPROSPECT_API_KEY!;
const prospectSearchId = process.env.PROSPECT_SEARCH_ID!;

const client = new OpenProspectClient(apiKey);

async function listCompanies() {
  try {
    const response = await client.listCompanies({
      prospectSearchId,
      limit: 50,
    });

    console.log(`Total companies: ${response.total}`);
    console.log(`Retrieved: ${response.items.length}`);
    console.log(`Has more: ${response.has_more}`);

    response.items.forEach((company) => {
      console.log(`- ${company.name} (Match: ${company.match_score})`);
    });
  } catch (error) {
    console.error("Error listing companies:", error);
  }
}

listCompanies();

Filter Companies

TypeScript
// examples/filter-companies.ts

import { OpenProspectClient } from "../openprospect-client";

const client = new OpenProspectClient(process.env.OPENPROSPECT_API_KEY!);
const prospectSearchId = process.env.PROSPECT_SEARCH_ID!;

async function filterCompanies() {
  try {
    const response = await client.listCompanies({
      prospectSearchId,
      minMatchScore: 7.0,
      reviewStatus: "accepted",
      limit: 20,
    });

    response.items.forEach((company) => {
      console.log(
        `${company.name} - ${company.city} - Score: ${company.match_score}`
      );
    });
  } catch (error) {
    console.error("Error filtering companies:", error);
  }
}

filterCompanies();

Get Single Company

TypeScript
// examples/get-company.ts

import { OpenProspectClient } from "../openprospect-client";

const client = new OpenProspectClient(process.env.OPENPROSPECT_API_KEY!);

async function getCompany(companyId: string) {
  try {
    const company = await client.getCompany(companyId);

    console.log(`Company: ${company.name}`);
    console.log(`Website: ${company.website}`);
    console.log(`Match Score: ${company.match_score}`);
    console.log(`Contacts: ${company.contacts.length}`);

    company.contacts.forEach((contact) => {
      console.log(`  - ${contact.name} (${contact.title}): ${contact.email}`);
    });
  } catch (error) {
    console.error("Error getting company:", error);
  }
}

getCompany("7f3e8c90-1234-5678-9abc-def012345678");

Pagination

Fetch All Companies

TypeScript
// utils/pagination.ts

import { OpenProspectClient } from "../openprospect-client";
import { Company } from "../types";

export async function getAllCompanies(
  client: OpenProspectClient,
  prospectSearchId: string,
  filters: {
    minMatchScore?: number;
    reviewStatus?: "accepted" | "rejected" | "pending" | "all";
    search?: string;
  } = {}
): Promise<Company[]> {
  const allCompanies: Company[] = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await client.listCompanies({
      prospectSearchId,
      limit,
      offset,
      ...filters,
    });

    allCompanies.push(...response.items);
    console.log(`Fetched ${allCompanies.length}/${response.total} companies...`);

    if (!response.has_more) {
      break;
    }

    offset += limit;
  }

  return allCompanies;
}

// Usage
import { OpenProspectClient } from "../openprospect-client";
import { getAllCompanies } from "../utils/pagination";

const client = new OpenProspectClient(process.env.OPENPROSPECT_API_KEY!);
const prospectSearchId = process.env.PROSPECT_SEARCH_ID!;

async function main() {
  const companies = await getAllCompanies(client, prospectSearchId, {
    minMatchScore: 7.0,
    reviewStatus: "accepted",
  });

  console.log(`Total companies retrieved: ${companies.length}`);
}

main();

Async Iterator Pattern

TypeScript
// utils/iterator.ts

import { OpenProspectClient } from "../openprospect-client";
import { Company } from "../types";

export async function* iterateCompanies(
  client: OpenProspectClient,
  prospectSearchId: string,
  filters: {
    minMatchScore?: number;
    reviewStatus?: "accepted" | "rejected" | "pending" | "all";
  } = {}
): AsyncGenerator<Company> {
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await client.listCompanies({
      prospectSearchId,
      limit,
      offset,
      ...filters,
    });

    for (const company of response.items) {
      yield company;
    }

    if (!response.has_more) {
      break;
    }

    offset += limit;
  }
}

// Usage
async function processCompanies() {
  const client = new OpenProspectClient(process.env.OPENPROSPECT_API_KEY!);
  const prospectSearchId = process.env.PROSPECT_SEARCH_ID!;

  for await (const company of iterateCompanies(client, prospectSearchId, {
    minMatchScore: 7.0,
  })) {
    console.log(`Processing: ${company.name}`);
    // Process each company as it's fetched
  }
}

Error Handling

Custom Error Class

TypeScript
// errors.ts

export class OpenProspectApiError extends Error {
  constructor(
    public statusCode: number,
    public errorCode: string,
    message: string
  ) {
    super(message);
    this.name = "OpenProspectApiError";
  }
}

// Update request method in OpenProspectClient
private async request<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  const url = `${this.baseUrl}${endpoint}`;
  const response = await fetch(url, {
    ...options,
    headers: {
      "Authorization": `Bearer ${this.apiKey}`,
      "Accept": "application/json",
      ...options.headers,
    },
  });

  if (!response.ok) {
    const error = await response.json();
    throw new OpenProspectApiError(
      response.status,
      error.error || "UNKNOWN_ERROR",
      error.message || response.statusText
    );
  }

  return response.json();
}

Error Handling Example

TypeScript
import { OpenProspectApiError } from "../errors";

async function listCompaniesWithErrorHandling() {
  try {
    const response = await client.listCompanies({
      prospectSearchId: process.env.PROSPECT_SEARCH_ID!,
      limit: 50,
    });
    console.log(`Retrieved ${response.items.length} companies`);
  } catch (error) {
    if (error instanceof OpenProspectApiError) {
      switch (error.statusCode) {
        case 401:
          console.error("Authentication failed - check your API key");
          break;
        case 403:
          console.error("Insufficient permissions");
          break;
        case 404:
          console.error("Prospect search not found");
          break;
        case 429:
          console.error("Rate limit exceeded");
          break;
        default:
          console.error(`API error: ${error.message}`);
      }
    } else {
      console.error("Unexpected error:", error);
    }
  }
}

Retry Logic

TypeScript
// utils/retry.ts

export async function retryWithBackoff<T>(
  fn: () => Promise<T>,
  maxRetries: number = 3,
  initialDelay: number = 1000
): Promise<T> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof OpenProspectApiError) {
        // Retry on rate limit or server errors
        if (error.statusCode === 429 || error.statusCode >= 500) {
          const delay = initialDelay * Math.pow(2, attempt);
          console.log(`Retrying in ${delay}ms... (attempt ${attempt + 1})`);
          await new Promise((resolve) => setTimeout(resolve, delay));
          continue;
        }
      }
      // Don't retry on client errors
      throw error;
    }
  }
  throw new Error(`Failed after ${maxRetries} retries`);
}

// Usage
const response = await retryWithBackoff(() =>
  client.listCompanies({
    prospectSearchId,
    limit: 50,
  })
);

Job Listings

Get Company Jobs

TypeScript
const companyId = "7f3e8c90-1234-5678-9abc-def012345678";

const jobsResponse = await client.getCompanyJobs({
  companyId,
  daysBack: 30,
  limit: 50,
});

console.log(`Total jobs: ${jobsResponse.total}`);
console.log(`Activity: ${jobsResponse.activity_strength}`);
console.log(`Velocity: ${jobsResponse.velocity_per_month} jobs/month`);

jobsResponse.jobs.forEach((job) => {
  console.log(`- ${job.title} on ${job.platform} (${job.date_posted})`);
});

Technology Stack

Get Company Technologies

TypeScript
const companyId = "7f3e8c90-1234-5678-9abc-def012345678";

const webtech = await client.getCompanyWebTech({
  companyId,
  minConfidence: 80,
});

console.log(`Total technologies: ${webtech.total}`);
console.log(`Scan successful: ${webtech.scan_successful}`);

webtech.technologies.forEach((tech) => {
  const version = tech.version ? ` (${tech.version})` : "";
  console.log(
    `- ${tech.name}${version} - ${tech.category} (${tech.confidence}% confidence)`
  );
});

Data Export

Export to JSON

TypeScript
import * as fs from "fs/promises";

async function exportToJson() {
  const companies = await getAllCompanies(client, prospectSearchId);

  await fs.writeFile(
    "companies.json",
    JSON.stringify(companies, null, 2),
    "utf-8"
  );

  console.log(`Exported ${companies.length} companies to companies.json`);
}

Export to CSV

TypeScript
import * as fs from "fs/promises";

async function exportToCsv() {
  const companies = await getAllCompanies(client, prospectSearchId);

  const headers = ["name", "city", "country", "website", "match_score", "business_type"];
  const csvRows = [
    headers.join(","),
    ...companies.map((company) =>
      [
        company.name,
        company.city || "",
        company.country || "",
        company.website || "",
        company.match_score,
        company.business_type || "",
      ].join(",")
    ),
  ];

  await fs.writeFile("companies.csv", csvRows.join("\n"), "utf-8");

  console.log(`Exported ${companies.length} companies to companies.csv`);
}

Rate Limit Handling

Rate Limit Aware Requests

TypeScript
async function getRateLimitedCompanies() {
  const allCompanies: Company[] = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await client.listCompanies({
      prospectSearchId,
      limit,
      offset,
    });

    allCompanies.push(...response.items);

    if (!response.has_more) {
      break;
    }

    offset += limit;

    // Rate limiting: 1 request per second
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }

  return allCompanies;
}

Next Steps