This API provides accurate information about the Lexus and Toyota dealer network in Europe. We have various amounts of public information such as opening hours, offered services and contact information.
This API is used to power features on the Toyota websites, but everyone is free to use it for their own use-cases.
The A2D-API requires oauth2 authentication, so you will need a valid bearer token (JWT). To be able to get a token you will need credentials (clientId/clientSecret) to AzureAD.
If you don't have credentials for your application, please fill out the following form to request credentials: https://forms.office.com/r/JKq5WkcfgK
curl -XGET -H 'Authorization: Bearer <your_token>' 'https://a2d-api-acc.toyota-europe.com/v2/_search'
To test your credentials, you can download this zip file. It contains an .http file that you can run via IntelliJ, and a consumer guide that can help you avoid common mistakes.
Environment | URL | Docs path | API path |
---|---|---|---|
Dev | https://a2d-api-dev.toyota-europe.com | /docs | /v2 |
Acc | https://a2d-api-acc.toyota-europe.com | /docs | /v2 |
Prd | https://a2d-api.toyota-europe.com | /docs | /v2 |
The dealers are represented by a common schema. The schema of the data is versioned. Older versions of the schema will be supported up to 6 months to help with the transition. Only breaking changes (such as changes in type of existing attributes) will cause the version to increase. This means that clients are supposed to ignore attributes they do not use. New attributes will only be added to the latest version of the schema.
You can specify a version of the schema in the Accept
header. The current A2D api no longer supports v1
, v2
and v3
. You can only use v4
, so your Accept
header should have the
value application/vnd.toyota-europe.a2d.v4+json
. The schema version is included in the response in the
custom X-A2d-Media-Type
header.
You need to provide a valid accept header.
Version 1, 2 and 3 are no longer supported!
If you are relying on fields which are not yet specified in the included json schema's, please drop us a line on A2D.Support@toyota-europe.com.
application/vnd.toyota-europe.a2d.v4+json
A field registryNumber was added on both outlet and operating company level. This information is often mandatory on official documents and communication on behalf of the dealer.
To support grouping of outlets these changes were made:
primaryOutletUuid
. This is not to be mistaken with the similarly named primaryOutlet
which still remains a boolean to indicate whether that Outlet is a primary Outlet.primaryOutlet
on OperatingCompany just containing one uuid, it now
represents a list of its primary outlet UUID's and has been renamed to primaryOutletUuids
.This grouping allows for another level of authorization in consuming applications.
For example, Toshiko will use this to populate a dropdown to list all the Outlets (branches) of the logged in users'
outlet's primary outlet.
Not all NMSC's are organised in this way, but TDG and TES are.
This allows for this kind of hierarchy:
DealerGroup (eg.: Llorente Spain)
|
|-----------------------------------------------------|---------------------------------------------|
Primary Dealer 1.1 (eg.: Llorente Madrid) Primary Dealer 2.1 (eg.: Llorente Barcelona) Primary Dealer 3.1 (eg.: Llorente Valencia)
| |
Dealer 1.2 (eg.: Llorente Madrid-South) Dealer 2.2 (eg.: Llorente Barcelona-South)
In the above example the result will sort of look like this (only relevant fields shown):
[
{
"name": "Llorente Madrid",
"primaryOutlet": true,
"uuid": "1.1",
"primaryOutletUuid": null,
"operatingCompany": {
"name": "Llorente Spain",
"uuid": "665",
"primaryOutletUuids": [
"1.1",
"2.1",
"3.1"
]
}
},
{
"name": "Llorente Madrid",
"primaryOutlet": false,
"uuid": "1.2",
"primaryOutletUuid": "1.1",
"operatingCompany": {
"name": "Llorente Spain",
"uuid": "665",
"primaryOutletUuids": [
"1.1",
"2.1",
"3.1"
]
}
},
{
"name": "Llorente Madrid",
"primaryOutlet": true,
"uuid": "2.1",
"primaryOutletUuid": null,
"operatingCompany": {
"name": "Llorente Spain",
"uuid": "665",
"primaryOutletUuids": [
"1.1",
"2.1",
"3.1"
]
}
},
{
"name": "Llorente Madrid",
"primaryOutlet": false,
"uuid": "2.2",
"primaryOutletUuid": "2.1",
"operatingCompany": {
"name": "Llorente Spain",
"uuid": "665",
"primaryOutletUuids": [
"1.1",
"2.1",
"3.1"
]
}
},
{
"name": "Llorente Valencia",
"primaryOutlet": true,
"uuid": "3.1",
"primaryOutletUuid": null,
"operatingCompany": {
"name": "Llorente Spain",
"uuid": "665",
"primaryOutletUuids": [
"1.1",
"2.1",
"3.1"
]
}
}
]
application/vnd.toyota-europe.a2d.v5+json
In version 5, the data is split into different domains, based on how the data is used.
The marketing domain contains all the data relevant for marketing purposes.
The marketing domain contains the hierarchy for the outlets. Every document consists of an outlet and the linked operating company and holding.
The dealer API is powered by Elasticsearch and exposes its API more or less directly. All queries you can do with Elasticsearch you can do here, provided the necessary Authorization headers are present.
To get you started we have provided some example queries. For more advances use cases we refer you to the Elasticsearch documentation
Here are some general pointers:
_count
endpoint rather than the _search
endpoint: this will return the number of
hits_search
endpoint explicitly asking for that number of hitshits.hits
array_source
objectmatch
query operator.terms
query on the <fieldname>.raw
non analyzed field. (See the examples)This section provides some example queries in curl format. They should be easy enough to adapt to your platform of choice.
Query
curl -XGET -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' 'https://a2d-api-acc.toyota-europe.com/v2/de/00CD0-E9EAD-1D654-90000-01350-3'
Output (Excerpt)
{
"_index": "v4_de_1571671591610",
"_type": "de",
"_id": "00CD0-E9EAD-1D654-90000-01350-3",
"_version": 1,
"found": true,
"_source": {
"addresses": [
{
"addressLine1": "Ollenhauer Str. 9-13",
"addressLine2": null,
"addressCode": "0",
"addressCountry": "DE",
"authorisedRepairer": true,
"authorisedRetailer": true,
"city": "Berlin",
...
}
],
"contactpersons": [],
...
}
}
Query
curl -XGET -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' 'https://a2d-api-acc.toyota-europe.com/v2/_search?q=uuid.raw:00CD0-E9EAD-1D654-90000-01350-3'
OR
curl -XGET -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' 'https://a2d-api-acc.toyota-europe.com/v2/_search?q=_id:00CD0-E9EAD-1D654-90000-01350-3'
Output (Excerpt)
{
"took": 98,
"timed_out": false,
"_shards": {
"total": 320,
"successful": 320,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 4.7985415,
"hits": [
{
"_index": "v4_de_1582799046789",
"_type": "de",
"_id": "00CD0-E9EAD-1D654-90000-01350-3",
"_score": 4.7985415,
"_source": {
"addresses": [
{
"addressLine1": "Ollenhauer Str. 9-13",
"addressLine2": null,
"addressCode": "0",
"addressCountry": "DE",
...
}
}
}
}
}
Query - With body
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api-acc.toyota-europe.com/v2/de/_search?pretty' -d '{
"query": {
"term": {"applications.NMSC.externalID": "68005"}
}
}'
Query - Inline
curl -XGET -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api-acc.toyota-europe.com/v2/de/_search?q=applications.NMSC.externalID:68005'
Output (Excerpt)
{
"_index": "v4_de_1571671591610",
"_type": "de",
"_id": "00CD0-E9EAD-1D654-90000-01350-3",
"_version": 1,
"found": true,
"_source": {
"addresses": [
{
"addressLine1": "Ollenhauer Str. 9-13",
"addressLine2": null,
"addressCode": "0",
"addressCountry": "DE",
"authorisedRepairer": true,
"authorisedRetailer": true,
"city": "Berlin",
...
}
],
"contactpersons": [],
...
}
}
Query - With body
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api-acc.toyota-europe.com/v2/de/_count?pretty' -d '{
"query": {
"term": {"brands.raw": "Lexus"}
}
}'
Query - Inline
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api.toyota-europe.com/v2/de/_count?q=brands.raw:Toyota&pretty'
Output
{
"count": 816,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
}
}
Query - With body
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api.toyota-europe.com/v2/de/_search?pretty' -d '{
"query": {
"term": {"brands.raw": "Toyota"}
},
"size": 100
}'
Query - Inline
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api.toyota-europe.com/v2/de/_search?q=brands.raw:Toyota&size=100&pretty'
Output (Excerpt)
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 817,
"relation": "eq"
},
"max_score": 0.073671006,
"hits": [
{
"_index": "v4_de_1571671591610",
"_type": "de",
"_id": "00CD4-260D0-0F5E6-95A00-01350-3",
"_score": 0.073671006,
"_source": {
"addresses": [
{
"addressLine1": "Einsteinstr. 1",
"addressLine2": null,
"addressCode": "0",
"addressCountry": "DE",
"authorisedRepairer": false,
"authorisedRetailer": false,
...
}
}
}
]
}
}
For history reasons, both Open and Closed outlets are exposed by A2D API. It might be that we need to find an outlet where we can try out a Toyota car before buying, so we need it to be Open and have the TestDrive operation.
Query
curl --location 'https://a2d-api.toyota-europe.com/v2/gb/_search' \
--header 'Accept: application/vnd.toyota-europe.a2d.v4+json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your token>' \
--data '{
"query":{
"bool":{
"must":[
{
"term":{
"brands.raw":"Toyota"
}
},
{
"term":{
"operations":{
"value":"TestDrive",
"case_insensitive":true
}
}
},
{
"term":{
"status":{
"value":"open",
"case_insensitive":true
}
}
}
]
}
}
}'
Output (Excerpt)
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 3.7077053,
"hits": [
{
"_index": "outlet_v4_gb_1650448414",
"_id": "929aed8c-04ab-4bcf-b423-4840010018ac",
"_score": 3.7077053,
"_source": {
"country": "GB",
"primaryOutletUuid": null,
"addresses": [
{
"addressLine1": "Broad Oak Road",
"addressLine2": null,
"zip": "CT2 7PX",
"city": "Canterbury",
"addressCountry": "GB",
"geoLocation": {
"lon": "1.0893886",
"lat": "51.292743"
},
"addressCode": null,
"usages": [],
"authorisedRepairer": false,
"authorisedRetailer": true,
"customRegion": null,
"defaultAddress": true,
"endDate": null,
"language": null,
"operations": [
"KintoOnePanE",
"TestDrive",
"UsedCars",
"OnlineServiceBooking",
"WorkShop",
"BodyShop",
"ShowRoom"
],
"province": "",
"region": "Kent & Sussex",
"startDate": null,
"status": "Active",
"vatRegion": ""
}
],
"outletMarketing": {
"sizeRate": false,
"marketingName": "Lexus Canterbury"
},
"language": null,
"latinName": null,
"dealerProfession": null,
"uuid": "929aed8c-04ab-4bcf-b423-4840010018ac",
"lastModificationDate": "04/06/2024 15:15:01.129",
"exceptionalOpeningHours": [],
"operations": [
"BodyShop",
"KintoOnePanE",
"MotabilityAffiliated",
"OnlineRetailing",
"OnlineServiceBooking",
"PaintShop",
"PartsShop",
"ShowRoom",
"TestDrive",
"UsedCars",
"WorkShop"
],
"primaryOutlet": false,
"outletNmsc": {
"virtualShowroom": true,
"zone": "Region 2",
"marketArea": "Kent & Sussex",
"driveSabEnterpriseId": "28776",
"previous_Dealer_Code": "000618",
"sizeRate": false,
"region": "Region 2",
"driveSabStoreId": "44019418"
},
"defaultEmail": "cc@steveneagell.co.uk",
"email": {
"ContactUs": [
"lexus-canterbury@lexus.co.uk",
"cc@steveneagell.co.uk"
],
"OSB": [
"lexus-canterbury@lexus.co.uk"
]
},
"introduction": null,
"brands": [
"Lexus"
],
"defaultPhoneNumber": "01227 213863",
...
"status": "Open"
}
},
...
]
}
}
If we want to restrict the search to a given country, the country code must be passed in the endpoint. Here it will be de
for Germany
https://a2d-api.toyota-europe.com/v2/de/_search?pretty
Query
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api.toyota-europe.com/v2/de/_search?pretty' -d '{
"query": {
"bool": {
"must": {
"term": {"brands.raw": "Lexus"}
},
"filter": {
"geo_distance": {
"distance": "30km",
"addresses.geoLocation" : {
"lat": 51.22,
"lon": 6.81
}
}
}
}
}
}'
Output (Excerpt)
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 2.6447554,
"hits": [
{
"_index": "v4_de_1571671591610",
"_type": "de",
"_id": "9443e886-b0f1-49e4-94ff-123c3fad4fa5",
"_score": 2.6447554,
"_source": {
"addresses": [
{
"addressLine1": "Höherweg 121-131",
"addressLine2": null,
"addressCode": null,
"addressCountry": "DE",
...
}
]
}
}
]
}
}
If the country code is not passed in the endpoint, there will be no country restriction and outlets from different countries might be returned by the api
https://a2d-api.toyota-europe.com/v2/_search?pretty
Query
curl -XPOST -H 'Authorization: Bearer <your_token>' -H 'Accept: application/vnd.toyota-europe.a2d.v4+json' -H 'Content-Type: application/json' 'https://a2d-api.toyota-europe.com/v2/_search?pretty' -d '{
"query": {
"bool": {
"must": {
"term": {"brands.raw": "Lexus"}
},
"filter": {
"geo_distance": {
"distance": "30km",
"addresses.geoLocation" : {
"lat": 51.22,
"lon": 6.81
}
}
}
}
}
}'
Output (Excerpt)
{
...
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 2.6447554,
"hits": [
{
"_index": "v4_de_1571671591610",
"_type": "de",
"_id": "9443e886-b0f1-49e4-94ff-123c3fad4fa5",
"_score": 2.6447554,
"_source": {
"addresses": [
{
"addressLine1": "Höherweg 121-131",
"addressLine2": null,
"addressCode": null,
"addressCountry": "DE",
...
}
]
}
}
]
}
}
If your application wants to monitor whether a2d-api is up-and-running, the following endpoint can be used:
Environment | URL | Health monitoring path |
---|---|---|
Dev | https://a2d-api-dev.toyota-europe.com | /v2/health |
Acc | https://a2d-api-acc.toyota-europe.com | /v2/health |
Prd | https://a2d-api.toyota-europe.com | /v2/health |
The response will contain the general status, which will be "200" if the application is running correctly. It will also contain a list of the a2d-api dependencies along with their status. These statuses will also be "200" when running correctly. If any dependency is failing, the general status will also reflect this.
If you have any other questions, you can send a mail to A2D.Support@toyota-europe.com.