CarsXECarsXE

The carsxe/carsxe Packagist package ships typed PHP 8.1 model classes for all CarsXE API responses. It does not bundle an HTTP client — use it alongside Guzzle (or any PSR-18 client) to make requests and hydrate the typed models from the JSON response. Requires PHP 8.1 or later.

Installation

composer require carsxe/carsxe guzzlehttp/guzzle

Quick start

<?php

require_once __DIR__ . '/vendor/autoload.php';

use CarsXE\Models\VehicleSpec;
use GuzzleHttp\Client;

$client = new Client(['base_uri' => 'https://api.carsxe.com']);

$response = $client->get('/specs', [
    'query' => [
        'key' => $_ENV['CARSXE_API_KEY'],
        'vin' => 'WBAFR7C57CC811956',
    ],
]);

$body = json_decode((string) $response->getBody(), true);
$spec = VehicleSpec::fromArray($body['data']);

echo "{$spec->year} {$spec->make} {$spec->model}\n";

Available models

ClassDescription
VehicleSpecFull vehicle specification (VIN, make, model, engine, etc.)
BulkRecallBatchJobCompleted bulk recall batch job
BulkRecallBatchJobPendingIn-progress bulk recall batch job
BulkRecallBatchResultResult row for a single VIN in a batch
BulkRecallBatchRowRaw recall row within a batch result

Each class exposes a static fromArray(array $data): self factory method that maps the API response directly to typed readonly properties.

Additional endpoints

The same Guzzle pattern works for every CarsXE endpoint — just change the path and query parameters. Decode the body with json_decode((string) $response->getBody(), true) as in Quick start.

// Market value (v2 — accepts state, mileage, and condition)
$response = $client->get('/v2/marketvalue', [
    'query' => [
        'key'     => $_ENV['CARSXE_API_KEY'],
        'vin'     => 'WBAFR7C57CC811956',
        'mileage' => 45000,
        'state'   => 'CA',
    ],
]);

// Safety recalls
$response = $client->get('/v1/recalls', [
    'query' => [
        'key' => $_ENV['CARSXE_API_KEY'],
        'vin' => '1C4JJXR64PW696340',
    ],
]);

// Vehicle history
$response = $client->get('/history', [
    'query' => [
        'key' => $_ENV['CARSXE_API_KEY'],
        'vin' => 'WBAFR7C57CC811956',
    ],
]);

// International VIN decoder (non-US VINs)
$response = $client->get('/v1/international-vin-decoder', [
    'query' => [
        'key' => $_ENV['CARSXE_API_KEY'],
        'vin' => 'WF0MXXGBWM8R43240',
    ],
]);

// License plate decoder
$response = $client->get('/platedecoder', [
    'query' => [
        'key'     => $_ENV['CARSXE_API_KEY'],
        'plate'   => '7XER187',
        'state'   => 'CA',
        'country' => 'US',
    ],
]);

// Vehicle images
$response = $client->get('/images', [
    'query' => [
        'key'   => $_ENV['CARSXE_API_KEY'],
        'make'  => 'BMW',
        'model' => 'X5',
        'year'  => '2019',
    ],
]);

// Year, make and model search
$response = $client->get('/v1/ymm', [
    'query' => [
        'key'   => $_ENV['CARSXE_API_KEY'],
        'year'  => '2012',
        'make'  => 'BMW',
        'model' => '5 Series',
    ],
]);

// OBD code decoder
$response = $client->get('/obdcodesdecoder', [
    'query' => [
        'key'  => $_ENV['CARSXE_API_KEY'],
        'code' => 'P0115',
    ],
]);

// Lien and theft records
$response = $client->get('/v1/lien-theft', [
    'query' => [
        'key' => $_ENV['CARSXE_API_KEY'],
        'vin' => '2C3CDXFG1FH762860',
    ],
]);

The two recognition endpoints are POST requests that take a JSON body with an image_url field. The API key still travels as a query parameter:

// Plate image recognition
$response = $client->post('/platerecognition', [
    'query' => ['key' => $_ENV['CARSXE_API_KEY']],
    'json'  => [
        'image_url' => 'https://imagedelivery.net/moyiiSImjJPI_EZVxNMBBw/f49aed53-d736-4370-f3f4-97418841c800/public',
    ],
]);

// VIN OCR from an image (URL or base64 string)
$response = $client->post('/v1/vinocr', [
    'query' => ['key' => $_ENV['CARSXE_API_KEY']],
    'json'  => [
        'image_url' => 'https://imagedelivery.net/moyiiSImjJPI_EZVxNMBBw/f49aed53-d736-4370-f3f4-97418841c800/public',
    ],
]);

Error handling

Guzzle throws GuzzleHttp\Exception\ClientException on 4xx responses and GuzzleHttp\Exception\ServerException on 5xx:

use GuzzleHttp\Exception\GuzzleException;

try {
    $response = $client->get('/specs', [
        'query' => ['key' => $_ENV['CARSXE_API_KEY'], 'vin' => 'WBAFR7C57CC811956'],
    ]);
    $body = json_decode((string) $response->getBody(), true);
    $spec = VehicleSpec::fromArray($body['data']);
} catch (GuzzleException $e) {
    // $e->getCode() → HTTP status
    // $e->getMessage() → error details
    error_log('CarsXE error: ' . $e->getMessage());
}

Best practices

Load your key from the environment. Never hardcode it.

// .env (loaded via vlucas/phpdotenv or similar)
CARSXE_API_KEY=your_key_here
$apiKey = $_ENV['CARSXE_API_KEY'] ?? getenv('CARSXE_API_KEY');

Reuse the Guzzle client. Instantiate it once (e.g. in a service container) and inject it — Guzzle reuses the underlying cURL handle pool.