Parking applications face a unique challenge: matching vehicles with suitable parking spaces. Whether it's ensuring a large truck can fit in a garage, directing EV owners to charging-enabled spots, or filtering results based on vehicle height restrictions, having accurate vehicle data is essential.

CarsXE provides two powerful APIs that parking companies can use to deliver intelligent, personalized parking experiences:

1. **Vehicle Plate Decoder API** - Get vehicle information from license plates
2. **Vehicle Specifications API** - Get detailed specifications from VINs

---

## Common Use Cases

### 1. Size-Based Parking Recommendations

**Challenge**: A truck owner in NYC needs to find parking spots that can accommodate their vehicle's dimensions.

**Solution**: Use CarsXE to automatically determine vehicle dimensions and filter parking options accordingly.

<PortableCode value={{
 language: "javascript",
 code: `// User enters license plate: "ABC1234"
  const plateData = await carsxe.platedecoder({
    plate: "ABC1234",
    state: "NY",
    country: "US"
  });

  // Get detailed specs from VIN
  const specs = await carsxe.specs({
    vin: plateData.vin
  });

  // Extract dimensions
  const dimensions = {
    length: specs.attributes.overall_length,    // e.g., "231.80 in."
    width: specs.attributes.overall_width,      // e.g., "80.00 in."
    height: specs.attributes.overall_height,    // e.g., "76.60 in."
  };

  // Filter parking spots
  const suitableSpots = parkingLocations.filter(spot => {
    return spot.maxLength >= parseDimension(dimensions.length) &&
           spot.maxWidth >= parseDimension(dimensions.width) &&
           spot.maxHeight >= parseDimension(dimensions.height);
  });
 `
}} />

**Key Vehicle Attributes**:
- `overall_length` - Total vehicle length
- `overall_width` - Total vehicle width
- `overall_height` - Total vehicle height
- `wheelbase_length` - Distance between front and rear axles
- `turning_diameter` - Turning radius for tight spaces

---

### 2. EV Charging Station Prioritization

**Challenge**: Show EV charging availability prominently to electric vehicle owners.

**Solution**: Detect if a vehicle is electric and highlight charging-enabled parking locations.

<PortableCode value={{
 language: "javascript",
 code: `// Decode license plate
  const plateData = await carsxe.platedecoder({
    plate: "TESLA99",
    state: "CA",
    country: "US"
  });

  // Get detailed specs
  const specs = await carsxe.specs({
    vin: plateData.vin
  });

  // Check if vehicle is electric
  const isEV = specs.attributes.fuel_type === "Electric" ||
               specs.attributes.fuel_type === "Plug-in Hybrid";

  // Customize UI for EV owners
  if (isEV) {
    // Show EV charging icon
    // Filter/sort by charging availability
    // Display charging rates and connector types
    // Show estimated charging time
  }
 `
}} />

**Fuel Types to Check**:
- `Electric` - Fully electric vehicles
- `Plug-in Hybrid` - PHEVs requiring charging
- `Gasoline` - Traditional gas vehicles
- `Diesel` - Diesel vehicles
- `Hybrid` - Non-plug-in hybrids

---

### 3. Vehicle Type Classification

**Challenge**: Different parking rates and restrictions for motorcycles, compact cars, SUVs, and commercial vehicles.

**Solution**: Automatically classify vehicles and apply appropriate pricing/restrictions.

<PortableCode value={{
 language: "javascript",
 code: `const specs = await carsxe.specs({ vin: userVIN });

  // Extract vehicle classification
  const vehicleType = specs.attributes.type;        // e.g., "Sedan/Saloon", "SUV", "Pickup"
  const bodyStyle = specs.attributes.style;         // e.g., "SEDAN 4-DR"
  const vehicleClass = specs.attributes.vehicle_class; // "1" (Light), "2" (Medium), etc.

  // Apply parking rules
  let parkingRate;
  let restrictions = [];

  if (vehicleType.includes("Pickup") || vehicleType.includes("SUV")) {
    parkingRate = rates.oversized;
    restrictions.push("Not suitable for compact spaces");
  } else if (vehicleType.includes("Sedan") || vehicleType.includes("Hatchback")) {
    parkingRate = rates.standard;
  } else if (vehicleType.includes("Motorcycle")) {
    parkingRate = rates.motorcycle;
    restrictions.push("Motorcycle parking only");
  }
 `
}} />

**Vehicle Classification Attributes**:
- `type` - General vehicle type (Sedan, SUV, Pickup, Motorcycle, etc.)
- `style` - Body style (SEDAN 4-DR, COUPE 2-DR, etc.)
- `category` - Vehicle category
- `vehicle_class` - Weight class (1=Light, 2=Medium, 3=Heavy)
- `size` - Size classification

---

### 4. Weight Restrictions

**Challenge**: Parking garages often have weight limits for structural safety.

**Solution**: Check vehicle weight against garage capacity.

<PortableCode value={{
 language: "javascript",
 code: `const specs = await carsxe.specs({ vin: userVIN });

  // Extract weight information
  const curbWeight = parseDimension(specs.attributes.curb_weight); // "4090 lbs"
  const gvwr = specs.attributes.gross_vehicle_weight_rating;
  const vehicleRating = specs.attributes.vehicle_rating; // "Light", "Medium", "Heavy"

  // Check against garage limits
  const garageMaxWeight = 6000; // lbs

  if (curbWeight > garageMaxWeight) {
    // Show warning or exclude location
    return {
      suitable: false,
      reason: \`Vehicle weight (\${curbWeight} lbs) exceeds garage limit (\${garageMaxWeight} lbs)\`
    };
  }
 `
}} />

---

## Implementation Guide

### Step 1: Capture Vehicle Information

Parking apps can capture vehicle data in several ways:

**Option A: License Plate Entry**
<PortableCode value={{
 language: "javascript",
 code: `// User manually enters their plate
  const plateData = await carsxe.platedecoder({
    plate: "7XER187",
    state: "CA",
    country: "US"
  });

  // Extract VIN for detailed specs
  const vin = plateData.vin;
 `
}} />

**Option B: VIN Entry**
<PortableCode value={{
 language: "javascript",
 code: `// User enters VIN directly (e.g., from registration)
  const specs = await carsxe.specs({
    vin: "WBAFR7C57CC811956"
  });
  `
}} />

**Option C: User Profile**
<PortableCode value={{
 language: "javascript",
 code: `// Store vehicle info in user profile on signup
// Retrieve for all future parking searches
const userVehicle = getUserProfile().vehicle;
`
}} />

---

### Step 2: Extract Key Data Points

Based on your parking application's needs, extract relevant attributes:

<PortableCode value={{
 language: "javascript",
 code: `const parkingRelevantData = {
    // Dimensions
    length: specs.attributes.overall_length,
    width: specs.attributes.overall_width,
    height: specs.attributes.overall_height,

    // Weight
    weight: specs.attributes.curb_weight,

    // Type
    vehicleType: specs.attributes.type,
    bodyStyle: specs.attributes.style,

    // Fuel
    fuelType: specs.attributes.fuel_type,
    isEV: specs.attributes.fuel_type === "Electric",

    // Capacity
    seating: specs.attributes.standard_seating,

    // Identity
    make: specs.attributes.make,
    model: specs.attributes.model,
    year: specs.attributes.year,

    // Additional
    turningDiameter: specs.attributes.turning_diameter
  };
  `
}} />

---

### Step 3: Filter & Personalize Results

Use the extracted data to customize the parking experience:

<PortableCode value={{
 language: "javascript",
 code: `function filterParkingLocations(spots, vehicleData) {
    return spots.filter(spot => {
      // Check dimensions
      if (spot.maxHeight &&
          parseDimension(vehicleData.height) > spot.maxHeight) {
        return false;
      }

      if (spot.maxLength &&
          parseDimension(vehicleData.length) > spot.maxLength) {
        return false;
      }

      // Check weight
      if (spot.maxWeight &&
          parseDimension(vehicleData.weight) > spot.maxWeight) {
        return false;
      }

      return true;
    }).map(spot => {
      // Add relevance score
      spot.relevanceScore = 0;

      // Boost EV charging spots for EV owners
      if (vehicleData.isEV && spot.hasEVCharging) {
        spot.relevanceScore += 10;
        spot.badges = spot.badges || [];
        spot.badges.push("EV Charging Available");
      }

      // Boost oversized spots for large vehicles
      if (parseDimension(vehicleData.length) > 200 && spot.oversized) {
        spot.relevanceScore += 5;
      }

      return spot;
    }).sort((a, b) => b.relevanceScore - a.relevanceScore);
  }
  `
}} />

---

## API Reference Quick Guide

### Vehicle Plate Decoder API

**Endpoint**: `GET https://api.carsxe.com/platedecoderr`

**Required Parameters**:
- `key` - Your CarsXE API key
- `plate` - License plate number
- `state` - Two-letter state code (for US, CA, AU)
- `country` - Two-letter country code (optional for US)

**Example Request**:
<PortableCode value={{
 language: "bash",
 code: `curl -G https://api.carsxe.com/platedecoderr \
  -d key=YOUR_API_KEY \
  -d plate=7XER187 \
  -d state=CA
`
}} />

**Key Response Fields**:
- `vin` - Vehicle Identification Number (use for detailed specs)
- `make` - Vehicle manufacturer
- `model` - Vehicle model
- `year` / `registration_year` - Model/registration year
- `description` - Full vehicle description

---

### Vehicle Specifications API

**Endpoint**: `GET https://api.carsxe.com/specs`

**Required Parameters**:
- `key` - Your CarsXE API key
- `vin` - 17-character Vehicle Identification Number

**Optional Parameters**:
- `format` - Response format (`json` or `xml`)
- `deepdata` - Set to `1` for additional data (slower response)

**Example Request**:
<PortableCode value={{
 language: "bash",
 code: `curl -G https://api.carsxe.com/specs \
  -d key=YOUR_API_KEY \
  -d vin=WBAFR7C57CC811956
`
}} />

**Key Response Fields for Parking Apps**:

| Attribute | Description | Example |
|-----------|-------------|---------|
| `overall_length` | Total vehicle length | "193.10 in." |
| `overall_width` | Total vehicle width | "73.20 in." |
| `overall_height` | Total vehicle height | "57.60 in." |
| `curb_weight` | Vehicle weight without cargo | "4090 lbs" |
| `fuel_type` | Type of fuel/power | "Electric", "Gasoline" |
| `type` | Vehicle type | "Sedan/Saloon", "SUV" |
| `style` | Body style | "SEDAN 4-DR" |
| `turning_diameter` | Turning circle | "37.50 in." |
| `wheelbase_length` | Wheelbase length | "116.90 in." |

---

## Best Practices

### 1. Cache Vehicle Data

Store vehicle information in user profiles to avoid repeated API calls:

<PortableCode value={{
 language: "javascript",
 code: `// On first lookup
  const specs = await carsxe.specs({ vin: userVIN });

  // Save to user profile
  await saveUserVehicle(userId, {
    vin: userVIN,
    specs: specs.attributes,
    lastUpdated: new Date(),
    cachedUntil: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days
  });

  // On subsequent searches
  const cachedVehicle = await getUserVehicle(userId);
  if (cachedVehicle && cachedVehicle.cachedUntil > new Date()) {
    // Use cached data
    return cachedVehicle.specs;
  } else {
    // Refresh from API
    return await carsxe.specs({ vin: userVIN });
  }
  `
}} />

### 2. Handle Missing Data Gracefully

Not all vehicles will have complete specification data:

<PortableCode value={{
 language: "javascript",
 code: `function parseDimension(value) {
    if (!value || value === "") return null;

    // Parse "193.10 in." to 193.10
    const parsed = parseFloat(value);
    return isNaN(parsed) ? null : parsed;
  }

  function checkDimensions(specs, spot) {
    const height = parseDimension(specs.attributes.overall_height);

    // If we don't have height data, show the spot with a warning
    if (!height && spot.maxHeight) {
      return {
        suitable: "unknown",
        warning: "Unable to verify vehicle height. Please check clearance manually."
      };
    }

    if (height && spot.maxHeight && height > spot.maxHeight) {
      return { suitable: false };
    }

    return { suitable: true };
  }
  `
}} />

### 3. Provide Visual Indicators

Help users understand why certain spots are recommended:

<PortableCode value={{
 language: "javascript",
 code: `function addParkingBadges(spot, vehicleData) {
    const badges = [];

    if (vehicleData.isEV && spot.hasEVCharging) {
      badges.push({
        icon: "⚡",
        text: "EV Charging",
        type: "success"
      });
    }

    if (vehicleData.length > 200 && spot.oversized) {
      badges.push({
        icon: "🚛",
        text: "Oversized Friendly",
        type: "info"
      });
    }

    if (spot.maxHeight > parseDimension(vehicleData.height) + 12) {
      badges.push({
        icon: "📏",
        text: "Plenty of Clearance",
        type: "success"
      });
    }

    return badges;
  }
  `
}} />

### 4. Error Handling

<PortableCode value={{
 language: "javascript",
 code: `async function getVehicleSpecs(plateOrVIN, isPlate = true) {
    try {
      if (isPlate) {
        const plateData = await carsxe.platedecoder({
          plate: plateOrVIN.plate,
          state: plateOrVIN.state,
          country: plateOrVIN.country
        });

        if (!plateData.success) {
          throw new Error("Unable to decode license plate");
        }

        if (!plateData.vin) {
          return {
            success: false,
            error: "VIN not available for this plate",
            basicInfo: plateData // Still return basic info
          };
        }

        const specs = await carsxe.specs({ vin: plateData.vin });
        return { success: true, data: specs };
      } else {
        const specs = await carsxe.specs({ vin: plateOrVIN });
        return { success: true, data: specs };
      }
    } catch (error) {
      console.error("Vehicle lookup error:", error);
      return {
        success: false,
        error: error.message,
        // Fallback: proceed with manual vehicle entry
        requiresManualEntry: true
      };
    }
  }
  `
}} />

---

## International Support

The Plate Decoder API supports license plates from 50+ countries across 6 continents. This enables global parking applications to serve diverse markets:

**North America**: US, Canada, Mexico, Costa Rica

**Europe**: UK, Germany, France, Spain, Italy, Netherlands, and 25+ more

**Asia**: India, China, Singapore, Malaysia, UAE, and more

**Oceania**: Australia, New Zealand

**South America**: Brazil, Argentina, Chile, Colombia, and more

**Africa**: South Africa, Nigeria, Tunisia

See the [full country list](/docs/v2/plate-decoder#international-support) in the Plate Decoder API documentation.

---

## Pricing & Trial

**Free Trial**: The Vehicle Specifications API is included in the 7-day free trial, allowing you to test integration before committing.

**Plate Decoder API**: Not included in the free trial. Visit our [pricing page](/pricing) for details.

**Production Use**: Contact sales for volume pricing and enterprise plans tailored to parking applications.

---

## Next Steps

1. [Sign up for a free API key](/signup)
2. Review the [Plate Decoder API documentation](/docs/v2/plate-decoder)
3. Review the [Specifications API documentation](/docs/v1/specifications)
4. Test the integration in your development environment
5. Contact [support@carsxe.com](mailto:support@carsxe.com) for integration assistance

---

## Example: Complete Parking Search Flow

Here's a complete example showing how a parking app might implement vehicle-aware search:

<PortableCode value={{
 language: "javascript",
 code: `import { CarsXE } from "carsxe-api";

  const carsxe = new CarsXE("YOUR_API_KEY");

  async function searchParking(userInput, parkingLocations) {
    // Step 1: Get vehicle data
    let vehicleData;

    if (userInput.plate) {
      const plateData = await carsxe.platedecoder({
        plate: userInput.plate,
        state: userInput.state,
        country: userInput.country || "US"
      });

      if (plateData.vin) {
        const specs = await carsxe.specs({ vin: plateData.vin });
        vehicleData = extractParkingData(specs.attributes);
      }
    } else if (userInput.vin) {
      const specs = await carsxe.specs({ vin: userInput.vin });
      vehicleData = extractParkingData(specs.attributes);
    }

    // Step 2: Filter locations
    const filteredSpots = parkingLocations.filter(spot => {
      return isVehicleSuitable(vehicleData, spot);
    });

    // Step 3: Rank by relevance
    const rankedSpots = filteredSpots.map(spot => ({
      ...spot,
      relevance: calculateRelevance(vehicleData, spot),
      badges: generateBadges(vehicleData, spot)
    })).sort((a, b) => b.relevance - a.relevance);

    return {
      vehicleData,
      results: rankedSpots,
      filteredCount: parkingLocations.length - filteredSpots.length
    };
  }

  function extractParkingData(attributes) {
    return {
      length: parseFloat(attributes.overall_length) || null,
      width: parseFloat(attributes.overall_width) || null,
      height: parseFloat(attributes.overall_height) || null,
      weight: parseFloat(attributes.curb_weight) || null,
      isEV: attributes.fuel_type === "Electric",
      isPHEV: attributes.fuel_type === "Plug-in Hybrid",
      type: attributes.type,
      make: attributes.make,
      model: attributes.model,
      year: attributes.year
    };
  }

  function isVehicleSuitable(vehicle, spot) {
    if (!vehicle) return true; // No vehicle data, show all

    if (spot.maxHeight && vehicle.height && vehicle.height > spot.maxHeight) {
      return false;
    }

    if (spot.maxLength && vehicle.length && vehicle.length > spot.maxLength) {
      return false;
    }

    if (spot.maxWeight && vehicle.weight && vehicle.weight > spot.maxWeight) {
      return false;
    }

    return true;
  }

  function calculateRelevance(vehicle, spot) {
    let score = 0;

    // EV charging match
    if ((vehicle.isEV || vehicle.isPHEV) && spot.hasEVCharging) {
      score += 20;
    }

    // Comfortable fit (not too tight)
    if (vehicle.height && spot.maxHeight) {
      const clearance = spot.maxHeight - vehicle.height;
      if (clearance > 12) score += 10; // 1 foot+ clearance
    }

    // Covered parking bonus for all
    if (spot.covered) score += 5;

    // Security features
    if (spot.security24_7) score += 5;

    return score;
  }

  function generateBadges(vehicle, spot) {
    const badges = [];

    if ((vehicle.isEV || vehicle.isPHEV) && spot.hasEVCharging) {
      badges.push({ text: "EV Charging", icon: "⚡", variant: "success" });
    }

    if (vehicle.length > 200 && spot.oversized) {
      badges.push({ text: "Large Vehicle OK", icon: "🚛", variant: "info" });
    }

    return badges;
  }

  // Usage
  const results = await searchParking(
    {
      plate: "7XER187",
      state: "CA"
    },
    allParkingLocations
  );
  `
}} />

---

## Support

Have questions about integrating CarsXE into your parking application?

- **Documentation**: [docs.carsxe.com](/docs)
- **Email**: [support@carsxe.com](mailto:support@carsxe.com)
- **API Status**: [status.carsxe.com](https://status.carsxe.com)

We're here to help you build better parking experiences!
