Skip to content

Repository files navigation

car-part-api

TypeScript client for Car-Part.com — the largest recycled/used auto parts marketplace in the US with 200M+ parts from thousands of auto recyclers.

  • Search by VIN (SmartVin auto-selects the right variant) or Year/Make/Model
  • Transparent interchange handling (1-step or 2-step flow)
  • 707 part types with common-name aliases
  • Full TypeScript types
  • Zero runtime dependencies
  • ESM + CommonJS

Install

npm install car-part-api

Quick Start

import { CarPartClient } from 'car-part-api';

const client = new CarPartClient({ zip: '32073' });

const results = await client.search({
  vin: '2C3CDXBG2JH247820',
  part: 'Caliper',
});

console.log(`Found ${results.results.length} used calipers`);
for (const r of results.results.slice(0, 5)) {
  console.log(`  ${r.year} ${r.model}${r.grade} grade — $${r.price}${r.distanceMiles} mi`);
}

API

new CarPartClient(options)

Option Type Default Description
zip string required ZIP code for distance calculations
location string 'All States' Region filter (see LOCATIONS)
sort SortOption 'price' Sort order: 'price', 'zip', 'grade', 'condition', 'year'
searchMode 'int' | 'exact' 'int' 'int' = interchange (recommended), 'exact' = exact match only
requestDelay number 1000 Min delay between requests (ms)
cache boolean | InterchangeCache false Cache interchange data to skip Step 1 on repeat searches

client.search(params): Promise<SearchResult>

Param Type Default Description
vin string 17-digit VIN (preferred — enables SmartVin)
year string Vehicle year (YMME fallback)
model string Make + model, e.g. 'Dodge Charger' (YMME fallback)
part string required Exact part name (see PART_NAMES)
location string client default Override location filter
sort SortOption client default Override sort order
page number 1 Results page
interchangeVariant number auto 0-based index to select a specific variant

Returns a SearchResult:

interface SearchResult {
  results: PartResult[];
  page: number;
  partSearched: string;
  interchangeVariant: string | null;  // Selected variant description
  allVariants: InterchangeVariant[];  // All available variants
  sessionId: string;
  searchMode: 'vin' | 'ymme';
}

Each PartResult:

interface PartResult {
  year: string;           // Donor vehicle year
  partName: string;       // e.g. 'Brake Caliper, Front Left'
  model: string;          // e.g. 'Dodge Charger'
  description: string;    // e.g. 'LH,SXT,3.6,8AT,FRONT'
  grade: string;          // 'A' (top), 'B', 'C', or '0' (ungraded)
  stockNumber: string;
  price: number;          // USD
  priceRaw: string;       // Original string, e.g. '$241.25'
  priceLabel: PriceLabel; // 'actual' | 'undmg' | 'canadian'
  priceCAD?: number;      // CAD price (Canadian dealers only)
  dealer: DealerInfo;
  distanceMiles: number;
  imageUrl: string | null;
  co2eSavingsKg: number | null;
}

client.getInterchangeVariants(params): Promise<InterchangeVariant[]>

Returns the available interchange variants without fetching results. Useful for presenting variant choices to users.

const variants = await client.getInterchangeVariants({
  vin: '2C3CDXBG2JH247820',
  part: 'Caliper',
});
// [
//   { description: 'front, 1 piston (opt BR3), LH', selected: true, ... },
//   { description: 'front, 1 piston (opt BR3), RH', selected: false, ... },
//   ...
// ]

searchParts(params) (convenience)

One-shot search without creating a client instance:

import { searchParts } from 'car-part-api';

const results = await searchParts({
  vin: '2C3CDXBG2JH247820',
  part: 'Engine Computer',
  zip: '32073',
});

resolvePartName(input): string | null

Resolves informal part names to exact Car-Part.com values:

import { resolvePartName } from 'car-part-api';

resolvePartName('ecm');           // 'Engine Computer'
resolvePartName('brake caliper'); // 'Caliper'
resolvePartName('headlight');     // 'Headlight Assembly'
resolvePartName('Alternator');    // 'Alternator' (exact match)

Constants

import { PART_NAMES, LOCATIONS, SORT_OPTIONS, PART_ALIASES } from 'car-part-api';

PART_NAMES;    // All 707 valid part names
LOCATIONS;     // All 96 location filter values
SORT_OPTIONS;  // ['price', 'zip', 'grade', 'condition', 'year']
PART_ALIASES;  // Common name -> exact name mapping

Examples

Search by Year/Make/Model

const results = await client.search({
  year: '2018',
  model: 'Dodge Charger',
  part: 'Headlight Assembly',
});

Select a specific interchange variant

// First, see what's available
const variants = await client.getInterchangeVariants({
  vin: '2C3CDXBG2JH247820',
  part: 'Caliper',
});
console.log(variants.map(v => v.description));
// ['front, 1 piston (opt BR3), LH', 'front, 1 piston (opt BR3), RH', ...]

// Then search with a specific variant
const results = await client.search({
  vin: '2C3CDXBG2JH247820',
  part: 'Caliper',
  interchangeVariant: 1, // RH caliper
});

Sort by distance

const results = await client.search({
  vin: '2C3CDXBG2JH247820',
  part: 'Alternator',
  sort: 'zip',
});

Enable caching

const client = new CarPartClient({
  zip: '32073',
  cache: true, // In-memory cache
});

// First search: 2 requests (interchange + results)
await client.search({ vin: '...', part: 'Caliper' });

// Second search for same part+vehicle: 1 request (cached interchange)
await client.search({ vin: '...', part: 'Caliper', page: 2 });

Custom cache (e.g. Redis)

import type { InterchangeCache } from 'car-part-api';

const redisCache: InterchangeCache = {
  async get(key) {
    const data = await redis.get(`carpart:${key}`);
    return data ? JSON.parse(data) : undefined;
  },
  async set(key, value) {
    await redis.set(`carpart:${key}`, JSON.stringify(value), 'EX', 3600);
  },
};

const client = new CarPartClient({ zip: '32073', cache: redisCache });

How It Works

Car-Part.com uses a CGI endpoint that returns HTML (not JSON). This library handles the full flow:

  1. POST with VIN/YMME + part name
  2. Detect response type — single variant returns results directly; multiple variants return an interchange selection page
  3. If interchange: parse hidden fields + radio buttons, select the correct variant (SmartVin auto-selects for VIN searches), POST again
  4. Parse the results HTML table into typed objects

No authentication required. No API key needed.

Parser Exports

For advanced use cases, the HTML parsers are exported directly:

import { detectResponseType, parseInterchangePage, parseResultsPage } from 'car-part-api';

const type = detectResponseType(html); // 'results' | 'interchange' | 'error'
const fields = parseInterchangePage(html); // InterchangeFields
const { results } = parseResultsPage(html); // PartResult[]

License

MIT

About

TypeScript client for Car-Part.com — search 200M+ recycled auto parts from thousands of salvage yards

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages