PlateAPIPlateAPI
DemoPricingDocsBlogLoginGet API Key
Demo→Pricing→Docs→Blog→Login→Get API Key→

Blog · 4 October 2026 · Updated 10 October 2026 · 6 min read

How to Link Auto Parts SKUs to Vehicles with Vehicle IDs

A plate lookup tells you what the customer drives. To turn that into "here are the parts that fit", every product in your catalogue needs to know which vehicles it fits. Most stores keep that as text -- "Toyota Hilux 2015-2020 2.8L diesel" -- and match it with string comparisons. That works until it does not. This guide shows the sturdier way: link each SKU to PlateAPI vehicle IDs once, then answer every lookup with a single query.

Why text matching breaks

Vehicle names are not consistent enough to match on:

  • Trims are often separate models. In the vehicle database, HILUX, HILUX SR and HILUX SR5 EXTRA CAB are three model names. A fitment line that says "Hilux" has to cover all of them.
  • Identical text can be different vehicles. The 2018 Mazda CX-5 has two 2.5L petrol AWD automatics with the same series (KF -KF4WL) and the same variant text. One is the 140kW engine, the other the 170kW turbo. A part that fits one may not fit the other.
  • Plate lookups and vehicle records can word things differently. The sandbox plate TEST123 returns model HILUX; the record for the same vehicle has model HILUX SR.

A vehicle_id removes the guesswork. It identifies one exact variant, it is the same whether it comes from a plate lookup or the vehicle database, and it does not change. One ID covers every model year of that variant, so a part that fits a 2015-2020 Hilux SR needs one row, not six.

Step 1: a fitment table

Many-to-many between your products and vehicle IDs:

sql
CREATE TABLE fitments (
  sku         text    NOT NULL,
  vehicle_id  integer NOT NULL,   -- PlateAPI vehicle_id
  PRIMARY KEY (sku, vehicle_id)
);
CREATE INDEX fitments_vehicle ON fitments (vehicle_id);

If your store platform has no database you control, the same data fits in a product custom field (a comma-separated list of IDs). The WooCommerce guide does it that way.

Step 2: map your catalogue once

For each fitment line, walk the vehicle database: every model name that starts with the base model, each year in the range, every series, the engines that match, and the vehicles under them. The Python SDK does the walk for you with walk_vehicles():

python
import csv, os
from plateapi import PlateAPI   # pip install plateapi

client = PlateAPI(os.environ["PLATEAPI_KEY"])

# Your fitment lines: SKU, make, base model, years, engine text
FITMENT = [
    ("OIL-FLT-123", "TOYOTA", "HILUX", 2015, 2020, "2.8L"),
    ("AIR-FLT-456", "MAZDA", "CX-5", 2018, 2018, "2.5L"),
]

with open("fitments.csv", "w", newline="") as f:
    out = csv.writer(f)
    out.writerow(["sku", "vehicle_id"])
    for sku, make, model, year_from, year_to, engine in FITMENT:
        for v in client.walk_vehicles(make, model, year_from=year_from,
                                      year_to=year_to, engine_contains=engine):
            out.writerow([sku, v.vehicle_id])
            print(sku, v.vehicle_id, v.model, v.engine)

The CX-5 line returns both 2.5L engines, each with its own ID (run on 4 October 2026, 1.9 seconds):

output
AIR-FLT-456 4453973 CX-5 2.5L,  PET PY I4 16v DOHC VVT Direct Inj {140kW}
AIR-FLT-456 6095835 CX-5 2.5L,  PET PY I4 16v DOHC VVT I/C Turbo Direct Inj {170kW}

If the filter fits only the non-turbo engine, narrow the text (engine_contains="VVT Direct Inj {140kW}") or delete the row you do not want. A wide walk, such as every Hilux trim from 2015 to 2020, is a few hundred requests and takes a minute or two at the SDK's default pace.

  • Store the IDs, not the text. IDs are stable; names and series strings can change.
  • Map every ID the walk returns unless you know a variant does not fit. Two records can share all their text and still be different vehicles.
  • Narrow by what makes the part specific: the engine string carries displacement, engine code and power; the variant text carries doors, body, drive and gearbox ("4D Ute", "4WD", "AT/MT").
  • The walk does not use lookup quota. The vehicle database is on Starter plans and above, with its own limit of 500 requests a minute.

Loading the result is one command, for example \copy fitments FROM 'fitments.csv' CSV HEADER in PostgreSQL.

Step 3: one query per lookup

A lookup returns a vehicle_id on the vehicle and on each alternative, plus a match field that tells you how sure the answer is:

  • "exact": one variant. Query its ID.
  • "multiple": several trims of one make and model, all on sale at the same time. Either show parts that fit any of them, or ask the customer to pick their trim and query that one ID.
  • "ambiguous": different models or generations. The vehicle has no ID (it would be a guess) and alternatives lists every candidate with its ID. Ask the customer to pick.
sql
-- match = "exact"
SELECT sku FROM fitments WHERE vehicle_id = 1380801;

-- match = "multiple": everything that fits any candidate
SELECT DISTINCT sku FROM fitments
WHERE vehicle_id IN (1380801, 1346446, 1330126);

In Python, result.candidate_ids gives you every non-null ID in order, ready for the IN list:

python
result = client.lookup(plate, state)
if not result.success:
    show_not_found()
elif result.match == "exact":
    show_parts(result.candidate_ids)    # one ID; empty if the variant is not certain
elif result.match == "multiple":
    show_parts(result.candidate_ids)    # or let the customer pick their trim
else:                                   # "ambiguous": different models or generations
    show_picker(result.alternatives)    # each alternative has its own vehicle_id

Keeping it current

  • New vehicles get new IDs. Re-run the mapping for products whose fitment has not been resolved yet; monthly is plenty. Never re-map rows you already have.
  • A lookup ID with no fitment rows is a mapping gap, not an unknown vehicle. Fetch the record with GET /api/v1/vehicles/{vehicle_id}, see what it is, and map the SKUs that fit.
  • Merged IDs still resolve. If the database once held one vehicle under two IDs, fetching the old ID returns the current record. Compare the vehicle_id you get back with the one you stored and update your row.
  • Basic records keep their ID. A vehicle first seen on a plate can start as a basic record (make, model, years and engine size) and keeps the same ID when its full record arrives.

What you need

Plate lookups work on every plan, including the free tier. The vehicle database, used for the one-off mapping and for make/model/year dropdowns, is on Starter ($79/month) and above, and its requests do not count toward your lookup quota. The vehicle database reference has the full SKU-linking section, and the lookup reference documents vehicle_id and match field by field.

PlateAPI turns Australian number plates into structured vehicle data -- one REST endpoint, all eight states, free tier included.

Try the live demo · API reference · Pricing

More from the blog

  • How to Add Rego Lookup to a WooCommerce Store
  • How to Add Rego Plate Lookup to Your Auto Parts Store
  • Year Make Model Lookup API -- Australia's Vehicle Database
PlateAPIPlateAPI

Australian vehicle registration plate lookup API. Operated by WolfStack Solutions, ABN 26 877 229 839, Melbourne, Australia.

[email protected]
(03) 9122 8765

ProductLive DemoPricingAPI ReferencePlate Lookup APIVehicle Database APIGitHubGet an API Key
CompanyBlogContactAPI StatusTerms of ServicePrivacy PolicySecurity
© 2026 WolfStack Solutions. All rights reserved.