PHPackages                             sashalenz/nhtsa-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. sashalenz/nhtsa-api

ActiveLibrary[API Development](/categories/api)

sashalenz/nhtsa-api
===================

Laravel integration package for the NHTSA vPIC API.

1.2.1(3w ago)0229MITPHPPHP ^8.4|^8.5

Since Oct 31Pushed 3w agoCompare

[ Source](https://github.com/sashalenz/nhtsa-laravel-api)[ Packagist](https://packagist.org/packages/sashalenz/nhtsa-api)[ RSS](/packages/sashalenz-nhtsa-api/feed)WikiDiscussions main Synced today

READMEChangelog (4)Dependencies (29)Versions (5)Used By (0)

NHTSA vPIC API for Laravel
==========================

[](#nhtsa-vpic-api-for-laravel)

A small, typed Laravel integration for the [NHTSA vPIC API](https://vpic.nhtsa.dot.gov/api/). It decodes VINs and WMIs into predictable DTOs, with built-in retries, optional proxying, and opt-in request-history logging.

Requirements
------------

[](#requirements)

- PHP 8.4 or 8.5
- Laravel 12 or 13

Installation
------------

[](#installation)

```
composer require sashalenz/nhtsa-api
```

The service provider and the `NhtsaApi` facade are auto-discovered. Publish the config only if you need to change the defaults:

```
php artisan vendor:publish --tag="nhtsa-api-config"
```

Configuration
-------------

[](#configuration)

`config/nhtsa-api.php`:

KeyEnvDefaultDescription`base_url``NHTSA_API_BASE_URL``https://vpic.nhtsa.dot.gov/api/`vPIC base URL.`timeout`—`10.0`Request and connection timeout, in seconds.`format``NHTSA_API_FORMAT``json`Response format query parameter.`retry.times`—`3`Attempts before failing. Set `0` to disable retries.`retry.sleep`—`150`Delay between attempts, in milliseconds.`proxy``NHTSA_API_PROXY``null`HTTP proxy: a URL string, a `Closure` resolved per request, or `null`.Usage
-----

[](#usage)

Every call goes through the `NhtsaApi` facade and accepts a request DTO.

### Decode a VIN — flat key/value (recommended)

[](#decode-a-vin--flat-keyvalue-recommended)

`decodeVinValues` returns one result keyed by NHTSA variable name. It is the most convenient shape for reading individual fields:

```
use Sashalenz\NhtsaApi\Data\Requests\DecodeVinRequestData;
use Sashalenz\NhtsaApi\Facades\NhtsaApi;

$result = NhtsaApi::decodeVinValues(
    DecodeVinRequestData::from(['vin' => '58ADA1C18MU003613'])
)->firstResult();

$make = $result?->get('Make');         // "LEXUS"
$model = $result?->get('Model');       // "ES"
$body = $result?->get('BodyClass');    // "Sedan/Saloon"
$year = $result?->get('ModelYear');    // "2021"
$fuel = $result?->get('FuelTypePrimary');
```

`get()` accepts a default: `$result->get('Trim', 'n/a')`. Use `->results()` to iterate every result row.

### Decode a VIN — variable list

[](#decode-a-vin--variable-list)

`decodeVin` returns the classic NHTSA variable list as `VinDecodedVariableData` items (`variable`, `value`, `valueId`, `variableId`):

```
$response = NhtsaApi::decodeVin(DecodeVinRequestData::from([
    'vin' => '5UXWX7C5*BA',
    'modelYear' => 2011, // optional, narrows ambiguous VIN patterns
]));

$make = $response->variables()->firstWhere('variable', 'Make')?->value;
```

### Decode a WMI

[](#decode-a-wmi)

```
use Sashalenz\NhtsaApi\Data\Requests\DecodeWmiRequestData;

$wmi = NhtsaApi::decodeWmi(DecodeWmiRequestData::from(['wmi' => '5UX']));
```

### Façade methods

[](#façade-methods)

MethodReturnsNotes`decodeVin``DecodeVinResponseData`Classic variable list.`decodeVinExtended``DecodeVinExtendedResponseData`Adds extended / NCSA variables.`decodeVinValues``VinDecodeFlatResponseData`Flat key/value result.`decodeVinValuesExtended``VinDecodeFlatResponseData`Flat, extended.`decodeWmi``DecodeWmiResponseData`WMI metadata.Service layer (request history)
-------------------------------

[](#service-layer-request-history)

`NhtsaApiService` wraps the client and logs every decode to the `nhtsa_api_requests` table — VIN, vehicle descriptor, make, model, model year, the raw decoded values, and a polymorphic link to the initiator.

```
use Sashalenz\NhtsaApi\Data\Requests\DecodeVinRequestData;
use Sashalenz\NhtsaApi\Services\NhtsaApiService;

$service = app(NhtsaApiService::class);

// Resolve just the make (and log the request, optionally attributed to a model).
$make = $service->determineMake(
    DecodeVinRequestData::from(['vin' => 'WP0AA2A7GL', 'modelYear' => 2016]),
    initiator: $user, // optional
);

// Full flat decode, logged.
$response = $service->decodeVinWithHistory(
    DecodeVinRequestData::from(['vin' => 'WP0AA2A7GL'])
);

// How many times this VIN has been looked up.
$count = $service->getVinRequestCount('WP0AA2A7GL');
```

Run the package migration to create the history table:

```
php artisan migrate
```

Error handling
--------------

[](#error-handling)

A non-2xx response (after the configured retries are exhausted) raises `NhtsaApiRequestException`:

```
use Sashalenz\NhtsaApi\Exceptions\NhtsaApiRequestException;

try {
    NhtsaApi::decodeVin(DecodeVinRequestData::from(['vin' => $vin]));
} catch (NhtsaApiRequestException $e) {
    // vPIC was unavailable — fall back to manual entry, queue a retry, etc.
}
```

Testing
-------

[](#testing)

The client is built on Laravel's HTTP client, so `Http::fake()` intercepts every request in your tests:

```
use Illuminate\Support\Facades\Http;

Http::fake([
    '*/DecodeVinValues/*' => Http::response([
        'Count' => 1,
        'Message' => 'Results returned successfully',
        'Results' => [['Make' => 'LEXUS', 'Model' => 'ES']],
    ]),
]);
```

Run the package's own suite:

```
vendor/bin/pest
```

License
-------

[](#license)

The MIT License (MIT). See [LICENSE](LICENSE) for details.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance90

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~73 days

Total

4

Last Release

24d ago

PHP version history (2 changes)1.0.0PHP ^8.4

1.1.0PHP ^8.4|^8.5

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/13202688?v=4)[Oleksandr Petrovskyi](/maintainers/sashalenz)[@sashalenz](https://github.com/sashalenz)

---

Top Contributors

[![sashalenz](https://avatars.githubusercontent.com/u/13202688?v=4)](https://github.com/sashalenz "sashalenz (5 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/sashalenz-nhtsa-api/health.svg)

```
[![Health](https://phpackages.com/badges/sashalenz-nhtsa-api/health.svg)](https://phpackages.com/packages/sashalenz-nhtsa-api)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.3k3](/packages/defstudio-telegraph)[spatie/laravel-query-builder

Easily build Eloquent queries from API requests

4.5k30.7M297](/packages/spatie-laravel-query-builder)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5021.9k](/packages/simplestats-io-laravel-client)[api-platform/laravel

API Platform support for Laravel

58171.4k14](/packages/api-platform-laravel)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1563.0k4](/packages/masterix21-laravel-licensing)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
