northbees / autotrader-api
A Laravel SDK for the Autotrader API - vehicles, valuations, stock management, finance, deals, and more.
Requires
- php: ^8.4
- illuminate/support: ^12.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- roave/security-advisories: dev-latest
This package is auto-updated.
Last update: 2026-03-06 21:35:09 UTC
README
A Laravel SDK for the Autotrader API - vehicles, valuations, stock management, finance, deals, and more.
Requirements
- PHP 8.4+
- Laravel 11 or 12
Installation
composer require northbees/autotrader-api
The package uses Laravel's auto-discovery, so the service provider will be registered automatically.
Publish the configuration file:
php artisan vendor:publish --tag=autotrader.config
Configuration
Add the following to your .env file:
AUTOTRADER_ENVIRONMENT=sandbox AUTOTRADER_KEY=your-api-key AUTOTRADER_SECRET=your-api-secret
See .env.example for all available options.
Authentication is handled automatically when any API call is made. The token will be cached.
Usage
The package is a lightweight wrapper around the Autotrader API.
Vehicle Request
// Basic Request $vehicle = app(AutotraderApi::class)->getVehicle($advertiserId, $vrm); // Request with mileage $vehicle = app(AutotraderApi::class)->getVehicle($advertiserId, $vrm, $mileage); // Request with mileage and additional data $vehicle = app(AutotraderApi::class)->getVehicle($advertiserId, $vrm, $mileage, [ 'features' => true, 'motTests' => false, 'history' => false, 'fullVehicleCheck' => false, 'valuations' => false, 'vehicleMetrics' => false, 'factoryCodes' => true, ]);
Search Request
// Basic search $results = app(AutotraderApi::class)->searchVehicles($advertiserId); // Search with criteria $results = app(AutotraderApi::class)->searchVehicles($advertiserId, [ 'make' => 'BMW', 'model' => 'X5', 'priceFrom' => 10000, 'priceTo' => 50000, 'factoryCodes' => ['FC123', 'FC456'], 'wheelbaseMM' => 2975, ]); // Search with monthly price option (replaces deprecated financeOption) $results = app(AutotraderApi::class)->searchVehicles($advertiserId, [ 'make' => 'BMW', 'monthlyPriceOption' => [ 'mileage' => 10000, 'deposit' => 1000, 'term' => 48, ], ]); // Search with additional options including financeOffers (headlineOffer) $results = app(AutotraderApi::class)->searchVehicles($advertiserId, $searchCriteria, [ 'features' => true, 'factoryCodes' => true, 'wheelbaseMM' => true, 'financeOffers' => true, // Includes headlineOffer in response ]);
Search API response notes:
financeOffers.headlineOffer: Available whenfinanceOffersoption is enabled (Aug 2025)vehicle.origin: Indicates if the vehicle is UK or Non UK specification (Oct 2025)rarityRating,valueRating: Autotrader intelligence ratings for vehicle features (Aug 2025)financeOptionsearch parameter is deprecated - usemonthlyPriceOptioninstead (Feb 2026)
Valuation Request
// To request a valuation, first complete a vehicle request $vehicle = app(AutotraderApi::class)->getVehicle($advertiserId, $vrm); // Then do a valuation lookup $valuation = app(AutotraderApi::class)->getValuation($advertiserId, $vehicle->derivativeId, $mileage, $vehicle->firstRegistrationDate); //You can also pass additional data to adjust your valuation $valuation = app(AutotraderApi::class)->getValuation($advertiserId, $vehicle->derivativeId, $mileage, $vehicle->firstRegistrationDate, [ 'totalPrice' => null, 'features' => null, 'conditionRating' => null, 'priceIndicatorRatingBands' => true, ]));
Future and Historic Valuation Requests
$historic = app(AutotraderApi::class)->getHistoricValuation($advertiserId, $vehicle->derivativeId, $historicOdometerReadingMiles, $firstRegistrationDate, $historicValuationDate); $future = app(AutotraderApi::class)->getFutureValuation($advertiserId, $vehicle->derivativeId, $futureOdometerReadingMiles, $firstRegistrationDate, $futureValuationDate);
Future and Historic Valuation API response notes:
amountNoVatGBPfields for retail, trade, and partExchange valuations are now available in Trended Valuations and Future Valuations APIs (Mar 2026) - LCVs only, produced alongsideamountExVatGBP
Taxonomy Requests
$taxonomy = app(AutotraderApi::class)->getVehicleTypes($advertiserId); /// Production status is optional, and can be Current, Discontinued or Future $taxonomy = app(AutotraderApi::class)->getMakes($advertiserId, $vehicleType, $productionStatus); $taxonomy = app(AutotraderApi::class)->getModels($advertiserId, $makeId, $model, $productionStatus); $taxonomy = app(AutotraderApi::class)->getGenerations($advertiserId, $modelId, $productionStatus); $taxonomy = app(AutotraderApi::class)->getDerivatives($advertiserId, $generationId, $productionStatus); // Search by OEM model code (e.g. Volvo derivatives) - requires generationId $taxonomy = app(AutotraderApi::class)->getDerivatives($advertiserId, $generationId, null, $oemModelCode); //Effective date is optional $taxonomy = app(AutotraderApi::class)->getFeatures($advertiserId, $derivativeId, $effectiveDate, $productionStatus, [ 'factoryCodes' => true, ]); $taxonomy = app(AutotraderApi::class)->getPrices($advertiserId, $derivativeId, $effectiveDate, $productionStatus); $taxonomy = app(AutotraderApi::class)->getTechnicalData($advertiserId, $derivativeId); // Facets are: fuelTypes, transmissionTypes, bodyTypes, trims, doors, drivetrains, wheelbaseTypes, cabTypes, axleConfigurations, badgeEngineSizes, styles, subStyles, endLayouts, bedroomLayouts $taxonomy = app(AutotraderApi::class)->getFacets( $advertiserId, $facet, $generationId, $productionStatus);
Taxonomy API response notes:
rarityRating,valueRating: Autotrader intelligence ratings for vehicle features (Aug 2025)- Manufacturer warranty details (paintwork, standard, corrosion, battery) available in Taxonomy and Vehicles APIs (Oct 2025)
Image Upload
$imageId = app(AutotraderApi::class)->addImage($advertiserId, $filePath);
Vehicle Metrics
$valuation = app(AutotraderApi::class)->getMetrics($advertiserId, $vehicle->derivativeId, $mileage, $vehicle->firstRegistrationDate); // With vatStatus for commercial vehicle No VAT valuations $valuation = app(AutotraderApi::class)->getVehicleMetrics($advertiserId, $derivativeId, $mileage, $firstRegistrationDate, [ 'vatStatus' => 'NO_VAT', ]);
Finance Requests
// Get finance options (quotes) $financeOptions = app(AutotraderApi::class)->getFinanceOptions($advertiserId, $vehicleData); // Submit finance application (note: only months fields are used, not years) // Use financeTerms.productType instead of deprecated financeTerms.product // Use applicant.replacingExistingLoan instead of deprecated affordability.replacingExistingLoan // Use applicant.lastName instead of deprecated applicant.surname $application = app(AutotraderApi::class)->submitFinanceApplication($advertiserId, [ 'monthsAtBank' => 40, // Previously would be yearsAtBank: 3, monthsAtBank: 4 'monthsAtEmployer' => 36, 'monthsAtAddress' => 48, 'financeTerms' => [ 'productType' => 'PCP', // Use productType, not deprecated product ], 'applicant' => [ 'lastName' => 'Smith', // Use lastName, not deprecated surname 'replacingExistingLoan' => true, // Use this, not deprecated affordability.replacingExistingLoan 'monthlyRentOrMortgage' => ['amountGBP' => 800], // Use this, not deprecated monthlyRentOrMortgageGBP 'monthlyChildcare' => ['amountGBP' => 200], // Use this, not deprecated monthlyChildCareGBP ], // ... other finance data ]); // Update finance application $updated = app(AutotraderApi::class)->updateFinanceApplication($advertiserId, $applicationId, $financeData); // Get a finance application by ID // Note: anonymised applications return {applicationId, status: "Expired"} instead of a 451 error $application = app(AutotraderApi::class)->getFinanceApplication($advertiserId, $applicationId); if (($application['status'] ?? null) === 'Expired') { // Application has been anonymised due to legal reasons }
Finance API field removals (Mar 2026):
financeTerms.producthas been removed - usefinanceTerms.productTypeproductin quotes/proposals has been removed - useproductTypeaffordability.replacingExistingLoanhas been removed - useapplicant.replacingExistingLoanaffordability.affordableLoanhas been removedproductNamehas been added to quotes for lender specific product name- Anonymised finance applications now return HTTP 200 with
{applicationId, status: "Expired"}instead of HTTP 451
Finance API field removals (Oct/Nov 2025):
applicant.surnamehas been removed - useapplicant.lastNameapplicant.monthlyRentOrMortgageGBP.amountGBPhas been removed - useapplicant.monthlyRentOrMortgage.amountGBPapplicant.monthlyChildCareGBP.amountGBPhas been removed - useapplicant.monthlyChildcare.amountGBPquestionsin quotes has been removed - usequotesRequirementsineligibilityReasonsin quotes has been removed - usequotesRequirementsproposalRequirementsandquotesRequirementsadded to Quotes response
Stock Requests
// Get stock list with new features $stock = app(AutotraderApi::class)->getStockList($advertiserId, $filters, [ 'factoryCodes' => true, 'priceIndicatorRatingBands' => true, 'wheelbaseMM' => true, ]); // Get real-time stock summary $summary = app(AutotraderApi::class)->getStockSummary($advertiserId, $stockId); // Update stock - mark as SOLD and unpublish tradeAdvert $updated = app(AutotraderApi::class)->updateStock($advertiserId, [ 'metadata' => ['stockId' => $stockId, 'lifecycleState' => 'SOLD'], 'adverts' => ['tradeAdvert' => ['status' => 'NOT_PUBLISHED']], ]);
Stock API response notes:
eligibleContractAllowances,allocatedContractAllowance: Contract allowance information (Aug 2025)vehicle.origin: Indicates if the vehicle is UK or Non UK specification (Oct 2025)- tradeAdvert can now be set to NOT_PUBLISHED when updating stock lifecycle to SOLD (Feb 2026)
Deals Requests
// Get all deals for an advertiser $deals = app(AutotraderApi::class)->getDeals($advertiserId); // Get deals with filters $deals = app(AutotraderApi::class)->getDeals($advertiserId, [ 'page' => 1, 'from' => '2023-05-05', 'to' => '2023-05-07', ]); // Get a specific deal $deal = app(AutotraderApi::class)->getDeal($advertiserId, $dealId); // Create a new deal (originated outside of Autotrader consumer journey) $deal = app(AutotraderApi::class)->createDeal($advertiserId, [ 'stockId' => $stockId, // ... deal data ]); // Complete a deal $response = app(AutotraderApi::class)->completeDeal($advertiserId, $dealId); // Cancel a deal with reason $response = app(AutotraderApi::class)->cancelDeal($advertiserId, $dealId, 'Unaffordable', 'Customer cannot afford the deposit'); // Update a deal with custom data $response = app(AutotraderApi::class)->updateDeal($advertiserId, $dealId, [ 'advertiserDealStatus' => 'Complete' ]); // Remove deal components $response = app(AutotraderApi::class)->removeDealPartExchange($advertiserId, $dealId); $response = app(AutotraderApi::class)->removeDealFinanceApplication($advertiserId, $dealId);
Deals API response notes:
buyingSignals: Consumer behaviour indicators including dealIntentScore, intent, localCustomer, advertSaved, preferences (Nov 2025)preferencesnow includeswheelbaseTypes(Mar 2026) - only available for Van consumer activity
reservationobject: Replaces deprecatedstock.reservationStatusandconsumerReservationFeeStatus. Includes status values Requested and Reserved (Jan 2026)stock.reservationStatusis deprecated - usereservationobject instead (Jan 2026)consumerReservationFeeStatusis deprecated - usereservationobject instead (Jan 2026)
Messages Requests
// Get messages for a specific message ID $messages = app(AutotraderApi::class)->getMessages($advertiserId, $messagesId); // Mark messages as read $response = app(AutotraderApi::class)->markMessagesAsRead($advertiserId, $messagesId); // Send a new message for a new conversation $response = app(AutotraderApi::class)->sendMessage($advertiserId, [ 'dealId' => '1a0e00aa-459b-162d-a23a-adcbb1110f04', 'message' => 'Your message here (max 1500 characters)' ]); // Send a message to an existing conversation $response = app(AutotraderApi::class)->sendMessage($advertiserId, [ 'messagesId' => 'e00a1a0a-162d-459b-a23a-0f04adcbb111', 'message' => 'Your reply message here' ]);
Delivery Requests
// Get delivery details $delivery = app(AutotraderApi::class)->getDelivery($advertiserId, $deliveryId); // Get call details $calls = app(AutotraderApi::class)->getCalls($advertiserId, $callId);
Integrations Requests
// Get integrations for the current partner $integrations = app(AutotraderApi::class)->getIntegrations();
Integrations API notes:
- Returns a view of what integrations a partner has access to (API, Datafeeds, Exports)
- For API integrations, shows all capabilities the integration has access to
- Introduced Nov 2025
Advertisers Requests
// Get advertisers $advertisers = app(AutotraderApi::class)->getAdvertisers();
Advertisers API response notes:
capabilitiesobject: Lists atConnect capabilities a partner's application is permitted to use on behalf of an advertiser (Oct 2025)
Valuation API Response Notes
amountNoVatGBPfields for retail, trade, and part exchange valuations are available for vehicles not requiring VAT (Aug 2025)- Also available in Historic Valuations and Vehicles APIs
Vehicle API Response Notes
rarityRating,valueRating: Autotrader intelligence ratings for vehicle features (Aug 2025)- Manufacturer warranty details (paintwork, standard, corrosion, battery) provided by manufacturer for brand new vehicles (Oct 2025)
Testing
composer test
Code Style
This package uses Laravel Pint for code style:
composer lint
Static Analysis
PHPStan with Larastan is used for static analysis:
composer analyse
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
License
The MIT License (MIT). Please see License File for more information.