CROP
ProjectsParts Services

K&M Tires API - Frontend Integration Guide

K&M Tire data is available through the Search API at .

K&M Tires API - Frontend Integration Guide

Overview

K&M Tire data is available through the Search API at https://api.crop-dev.app/api/search.

Index Statistics:

  • Total tires: 7,091
  • With GCP images: 5,018 (~71%)
  • With any image: ~90% (some use original K&M CDN)
  • All have prices (100%)

Image Hosting

✅ Images are now hosted on GCP Cloud Storage (WebP format)

https://storage.googleapis.com/crop-tire-images/tires/{slug}.webp

Example:

https://storage.googleapis.com/crop-tire-images/tires/kmt-04493560000.webp

Benefits of GCP hosting:

  • ✅ SEO: Images indexed under crop.com domain
  • ✅ Performance: WebP format (60-95% smaller than original PNG)
  • ✅ Reliability: No dependency on external CDN
  • ✅ Control: Can optimize, resize, add watermarks
  • ✅ Caching: 1-year browser cache headers

Note: ~29% of tires still use original K&M CDN URLs (migration failed due to 404 on source). Check media.hasGcpImages to distinguish.

API Endpoints

Search Tires

GET /api/search?manufacturer=kmt

Query Parameters:

ParameterTypeDescription
manufacturerstringUse kmt for K&M Tires
qstringSearch query (brand, size, model)
specBrandstring/string[]Filter by tire brand (Firestone, Goodyear, etc.)
specTireSizestring/string[]Filter by tire size (265/65R17, 11.2-24, etc.)
priceMinnumberMinimum price filter
priceMaxnumberMaximum price filter
pagenumberPage number (default: 1)
pageSizenumberResults per page (default: 20, max: 100)
sortBystringrelevance, price_asc, price_desc

Get Filters/Facets

GET /api/filters?manufacturer=kmt

Returns available filter values for building filter UI.

Tire Document Structure

interface TireDocument {
  // Identifiers
  id: string;                    // MongoDB ObjectId
  slug: string;                  // URL-friendly ID: "kmt-04493560000"
  partNumber: string;            // K&M part number: "04493560000"
  sku: string;                   // Full SKU: "CT-KMT-04493560000"
  vendorCode: string;            // Alias for sku

  // Display
  title: string;                 // "General GE 265/65R17/SL GRAB HT OL 112T 265/65R17"
  description: string;           // Detailed description with specs

  // Manufacturer
  manufacturer: {
    code: string;                // "KMT"
    name: string;                // "K&M Tire"
    slug: string;                // "kmt"
    catalogHref: string;         // "/manufacturers/kmt/catalog"
    partsHref: string;           // "/manufacturers/kmt/parts"
  };

  // Tire Specifications (key fields for filtering)
  specifications: {
    "Brand": string;             // "Firestone", "Goodyear", "General", etc.
    "Tire Size": string;         // "265/65R17", "11.2-24", "14.9-28"
    "Model": string;             // Full model name
    "Speed Rating"?: string;     // "T", "H", "S", etc.
    "Load Index"?: string;       // "112", "116", etc.
    "Rim Diameter"?: string;     // "17", "24", etc.
    "Width"?: string;            // "265", "11.2", etc.
    "Aspect Ratio"?: string;     // "65", etc.
    "Free Freight"?: string;     // "Yes" | "No"
    "K&M Vendor ID"?: string;    // Internal vendor ID
  };

  // Images
  media: {
    hasImage: boolean;           // true if image available
    hasGcpImages: boolean;       // true (images hosted on GCP)
    imagesCount: number;         // Usually 1
    images: Array<{
      url: string;               // GCP WebP URL
      type: string;              // "marketing"
      source: string;            // "gcp"
      originalUrl?: string;      // Original K&M CDN URL (for reference)
      sortOrder: number;         // 0
    }>;
  };

  // Pricing
  price: {
    list: {
      value: number;             // Price in dollars (e.g., 162)
      currency: string;          // "USD"
    };
  };

  // Inventory
  inventory: {
    availability: string;        // "in_stock" | "out_of_stock"
    stock: number;               // Quantity available
    kmStock: number;             // K&M warehouse stock
    kmAvailable: boolean;        // Quick availability check
    kmCheckedAt: string;         // ISO timestamp of last check
  };
  availability: string;          // Top-level: "in_stock" | "out_of_stock"

  // Category
  category: Array<{
    id: string;                  // "wheels-tires"
    name: string;                // "Wheels & Tires"
    path: string;                // "Wheels & Tires"
    slug: string;                // "wheels-tires"
    level: number;               // 1
    leaf: boolean;               // true
  }>;
  categoryPath: string[];        // ["Wheels & Tires"]
  categoryId: string[];          // ["wheels-tires"]

  // Status
  status: string;                // "active" | "discontinued"
  isTopSeller: boolean;          // false for most tires
}

Image URLs

All K&M tire images are hosted on GCP Cloud Storage (WebP format):

https://storage.googleapis.com/crop-tire-images/tires/{slug}.webp

Example:

https://storage.googleapis.com/crop-tire-images/tires/kmt-04493560000.webp

Image Access:

// Get primary image URL
const imageUrl = tire.media.images[0]?.url;

// Check if image exists
const hasImage = tire.media.hasImage;

// Check if using GCP (new format)
const isGcpImage = tire.media.images[0]?.source === 'gcp';

Sample API Responses

Search Response

curl 'https://api.crop-dev.app/api/search?manufacturer=kmt&pageSize=2'
{
  "parts": [
    {
      "id": "6970d1a2b8853c982bd3ff9e",
      "partNumber": "04493560000",
      "title": "General GE 265/65R17/SL GRAB HT OL 112T 265/65R17",
      "slug": "kmt-04493560000",
      "manufacturer": {
        "code": "KMT",
        "name": "K&M Tire"
      },
      "specifications": {
        "Brand": "General",
        "Tire Size": "265/65R17",
        "Model": "GE 265/65R17/SL GRAB HT OL 112T"
      },
      "media": {
        "hasImage": true,
        "hasGcpImages": true,
        "imagesCount": 1,
        "images": [{
          "url": "https://storage.googleapis.com/crop-tire-images/tires/kmt-04493560000.webp",
          "type": "marketing",
          "source": "gcp",
          "originalUrl": "https://nyc3.digitaloceanspaces.com/km-tire-images/images/tireimages/141/141m.png"
        }]
      },
      "price": {
        "list": { "value": 162, "currency": "USD" }
      },
      "inventory": {
        "availability": "out_of_stock",
        "stock": 0
      }
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 2,
    "total": 7091,
    "totalPages": 3546
  }
}

Filters Response

curl 'https://api.crop-dev.app/api/filters?manufacturer=kmt'

Returns facets for:

  • specBrand - Tire brands (Firestone, Goodyear, General, Titan, etc.)
  • specTireSize - Tire sizes (265/65R17, 11.2-24, etc.)
  • price - Price ranges and stats

Filtering Examples

By Tire Brand

GET /api/search?manufacturer=kmt&specBrand=Firestone
GET /api/search?manufacturer=kmt&specBrand=Firestone&specBrand=Goodyear

By Tire Size

GET /api/search?manufacturer=kmt&specTireSize=265/65R17
GET /api/search?manufacturer=kmt&specTireSize=11.2-24

Combined Filters

GET /api/search?manufacturer=kmt&specBrand=Firestone&specTireSize=265/65R17&priceMax=300

Search by Text

GET /api/search?manufacturer=kmt&q=firestone+tractor
GET /api/search?manufacturer=kmt&q=265/65R17

Frontend Integration Tips

1. Display Primary Image

function getTireImage(tire: TireDocument): string | null {
  if (!tire.media?.hasImage) return null;
  return tire.media.images[0]?.url ?? null;
}

2. Format Price

function formatPrice(tire: TireDocument): string {
  const price = tire.price?.list?.value;
  if (!price) return 'Contact for price';
  return `$${price.toFixed(2)}`;
}

3. Get Tire Specs

function getTireSpecs(tire: TireDocument) {
  const specs = tire.specifications;
  return {
    brand: specs?.Brand,
    size: specs?.['Tire Size'],
    model: specs?.Model,
    speedRating: specs?.['Speed Rating'],
    loadIndex: specs?.['Load Index'],
  };
}

4. Check Availability

function isInStock(tire: TireDocument): boolean {
  return tire.inventory?.availability === 'in_stock'
      || tire.availability === 'in_stock';
}

Available Tire Brands

Sample brands in the database:

  • Firestone
  • Goodyear
  • General
  • Titan
  • Nexen
  • BKT
  • Galaxy
  • Carlisle
  • And more...

Use /api/filters?manufacturer=kmt to get the complete list with counts.

Notes

  1. Image Source: ~71% hosted on GCP Cloud Storage (WebP format, source: "gcp"), rest on K&M CDN (source: "km-cdn")
  2. Original URLs: Original K&M CDN URLs preserved in originalUrl field for GCP-migrated images
  3. Inventory: Stock data is updated periodically (see kmCheckedAt)
  4. Pricing: All tires have list prices in USD
  5. Category: All tires are in "Wheels & Tires" category
  6. GCP Detection: Use media.hasGcpImages === true to check if image is on GCP

Image Migration (Admin)

Prerequisites

# Install dependencies
bun install

# Authenticate with GCP
gcloud auth login
gcloud auth application-default login

Setup GCP Bucket

cd services/search
./scripts/setup-gcp-tire-images-bucket.sh crop-marketplace-prod crop-tire-images

Run Migration

# Preview (dry run)
bun scripts/migrate-tire-images-to-gcp.ts --dry-run --limit=10

# Run full migration
bun scripts/migrate-tire-images-to-gcp.ts

# Resync Elasticsearch after migration
bun scripts/sync-mongodb-to-es.ts --collection parts_kmt

Migration Details

The script:

  1. Downloads images from K&M CDN
  2. Converts PNG → WebP (30-50% smaller)
  3. Uploads to GCP Cloud Storage
  4. Updates MongoDB with new URLs
  5. Sets media.images[0].source to "gcp"

Verify Migration

# Check a migrated tire
curl -s 'https://api.crop-dev.app/api/search?manufacturer=kmt&pageSize=1' | \
  jq '.parts[0].media.images[0]'

# Expected output:
# {
#   "url": "https://storage.googleapis.com/crop-tire-images/tires/kmt-04493560000.webp",
#   "source": "gcp",
#   "type": "marketing",
#   "originalUrl": "https://nyc3.digitaloceanspaces.com/km-tire-images/images/tireimages/141/141m.png"
# }

# Test GCP image URL directly
curl -I 'https://storage.googleapis.com/crop-tire-images/tires/kmt-167182007.webp'
# Expected: HTTP/2 200, Content-Type: image/webp

On this page