virtuallast / adt-php-client
A strongly typed PHP client for the Applied Driving ADT API.
Requires
- php: ^8.3
- ext-json: *
- jane-php/open-api-runtime: ^7.0
- php-http/client-common: ^2.7
- php-http/discovery: ^1.20
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- symfony/serializer: ^7.4 || ^8.0
Requires (Dev)
- jane-php/open-api-3: ^7.0
- nyholm/psr7: ^1.8
- phpdocumentor/shim: ^3.10
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5 || ^12.0
- symfony/console: ^7.4 || ^8.0
- symfony/http-client: ^7.4 || ^8.0
- symfony/process: ^7.4 || ^8.0
Suggests
- nyholm/psr7: Recommended PSR-7 and PSR-17 implementation.
- symfony/http-client: Recommended PSR-18 HTTP transport.
README
A strongly typed PHP 8.3+ client for the Applied Driving ADT API v2.2. Jane-generated endpoints and models provide faithful wire types; the stable hand-written surface provides configuration, authentication, resource grouping, pagination, dates, exceptions, and PSR dependency integration.
Installation
composer require virtuallast/adt-php-client
An installed PSR-18 client and PSR-17 factories are discovered automatically. Symfony HTTP Client and Nyholm PSR-7 are suggested implementations.
Quick start and authentication
The official specification requires an API key in X-API-Key and advertises live and development servers.
use VirtualLast\Adt\AdtClient; use VirtualLast\Adt\Configuration; $client = AdtClient::create(new Configuration($_ENV['ADT_API_KEY'])); $page = $client->users()->list(take: 100);
To use the documented development server, pass Environment::Development. For explicit PSR injection:
$client = AdtClient::create($configuration, $psr18Client, $requestFactory, $streamFactory);
Users
The users API supports every documented user collection write: create, update, and delete.
use VirtualLast\Adt\Generated\Model\UserCreateRequest; use VirtualLast\Adt\Generated\Model\UserUpdateRequest; $create = (new UserCreateRequest()) ->setEmail('driver@example.com') ->setFirstName('Example') ->setLastName('Driver'); $created = $client->users()->create($create); $updated = $client->users()->update($created->getUserId(), (new UserUpdateRequest())->setFirstName('Updated')); $client->users()->delete($updated->getUserId());
Set actual fields through the generated request-model setters required by your ADT account workflow. For pagination, list() returns one UserReport; iterate() lazily advances skip by returned records and never retains all pages:
foreach ($client->users()->iterate(take: 500) as $user) { // $user is Generated\Model\User }
modifiedAfter accepts DateTimeInterface and preserves its supplied offset in RFC 3339 form. Telematics date path parameters use the same rule.
Resource groups
users()— list, lazy iteration, create, update, delete, and deleted-user reports.reports()— reminders, vehicle categories, extended user data, licence, courses, training progress, progress, Ultra, risk, and endorsements.telematics()— weekly event and per-kilometre reports with the three documented date-range variants.
generated() deliberately provides advanced access to all 22 generated operations. It follows upstream naming and is less stable than grouped APIs.
Errors
Catch AdtException; specialized exceptions cover configuration, authentication, API status, and transport failures. Exceptions retain causes while omitting API keys, authorization headers, and bodies. The package performs no general retry, including for documented rate limits.
Maintaining the specification
composer update-spec
composer process-spec
composer validate-spec
composer generate
composer update-client
composer test
composer analyse
composer validate
The unmodified upstream document lives at openapi/source/swagger.json; deterministic Jane input lives at openapi/processed/openapi.json. See openapi/README.md. Never edit generated/ manually.
PHP API reference
Generate browsable reference documentation for the stable SDK surface and generated models with:
composer docs
The output is written to build/docs/php. Generated endpoints, normalizers, and
runtime internals are intentionally excluded; use generated() and the upstream
OpenAPI documentation when advanced endpoint-level access is required.
Current limitations
The upstream document defines only successful responses, so API error bodies and correlation identifiers are not typed. Its development server is documented only by name and URL. No live integration test is enabled, and compatibility with a real ADT account is therefore not claimed.