Toyota Europe Dealers API

Overview

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.

Authorization

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

Example

curl -XGET -H 'Authorization: Bearer <your_token>' 'https://a2d-api-acc.toyota-europe.com/v2/_search'

Test credentials

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.

Environments

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

Schema and Versions

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.

Version 4

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:

  • New field added to an Outlet: 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.
  • Changed field in OperatingCompany: Instead of 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"
      ]
    }
  }
]

Version 5

  • Accept Header: application/vnd.toyota-europe.a2d.v5+json

In version 5, the data is split into different domains, based on how the data is used.

Marketing domain

The marketing domain contains all the data relevant for marketing purposes.

Access control domain

The marketing domain contains the hierarchy for the outlets. Every document consists of an outlet and the linked operating company and holding.

API

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:

  • If you want to search on multiple fields, you need to use a bool query
  • By default, the API will return the first 10 documents, if you need more you should explicitly specify a higher upper bound or paginate using an offset. Another way to go around this is to use two queries:
    1. Run the query against the _count endpoint rather than the _search endpoint: this will return the number of hits
    2. Run the query against the _search endpoint explicitly asking for that number of hits
  • If you really need more than 10 documents, you can specify the size parameter, but please limit the size to max 500. We noticed performance decrease when using it with a high number.
  • The output is contained in the hits.hits array
  • The dealer document is contained in the _source object
  • All string fields are analyzed, which means they do a fuzzy match. If you want to query them you need to use a match query operator.
  • Exact match queries can be done using a terms query on the <fieldname>.raw non analyzed field. (See the examples)

Examples

This section provides some example queries in curl format. They should be easy enough to adapt to your platform of choice.

Get dealer via UUID

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": [],
    ...
  }
}

Get dealer via UUID, without specifying a countrycode

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",
              ...
            }
          }
          }
          }
          }

Get dealer via local system ID

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": [],
    ...
  }
}

Get the number of Lexus dealers in Germany

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
  }
}

Get all Toyota dealers for Germany

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,
              ...
            }
          }
          }
          ]
        }
      }

Get all Toyota dealers in GB whose outlet is Open and have a TestDrive operation

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"
                }
            },
            ...
        ]
    }
}

Get all Lexus dealers in a 30 km radius around a location - in a specific country

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",
              ...
            }
          ]
        }
      }
    ]
  }
}

Get all Lexus dealers in a 30 km radius around a location - over multiple countries

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",
              ...
            }
          ]
        }
      }
    ]
  }
}

Health Monitoring

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.

Support

If you have any other questions, you can send a mail to A2D.Support@toyota-europe.com.