Decision guides
Each guide starts with what the caller actually has, then selects a documented goal and public operation. The OpenAPI contract remains authoritative for exact schemas and errors. If a branch below says “not documented”, stop rather than inventing an endpoint.
I have a VIN
Goal: retrieve vehicle data
- Call
GET /vin/{vin}/vehiclewith the request parameters documented for the customer contract. - If the response requires a browser redirect, follow the documented redirect-session flow; otherwise consume the direct result.
- Read
tapiId, the returned selection value and the documented vehicle data from the success response. - Persist the VIN and
tapiIdseparately;tapiIdrepresents the matched technical vehicle type, not the individual physical car. - Continue with
GET /vehicles/{tapiId}for technical vehicle data orPOST /vehicles/{tapiId}/listingfor listing text when needed.
Treat the numeric selection value as an opaque contract value. Do not infer capabilities, suppliers or data provenance from it.
Goal: retrieve vehicle-related parts
- Call
GET /vin/{vin}/partswith a full VIN and the request parameters documented for the customer contract. - Keep the optional numeric selection consistent for the same VIN. A conflicting value returns
409 vin_provider_mismatch. - On
200, mapparts[], including each requiredtapiGenArtandvdifield, plusmatchLevel,providerand the returnedtapiIdaccording to the schema. Preservevdi=[]as the complete value for a position without a valid mapping. - On
202, persist the job and poll the required fullstatusUrlwithGET /vin/parts/jobs/{jobId}afterRetry-After. CompareLocationwith that documented URL and quarantine a mismatch rather than resolving its current root-relative example against the API origin. - Treat
matchLevelas part of the result, not optional display text.
Do not retry the order merely because it returned 202. Do not discard positions. A successful VIN-parts position always includes exactly one tapiGenArt and one vdi array; an empty vdi array does not keep the job pending.
Goal: check an OE-number cart against the VIN
Use POST /vin/cart-check, not a parts lookup or SEO response. On 202, poll GET /vin/cart-check/jobs/{jobId}. Interpret the line results and the overall completeness field together. A negative line result in an incomplete comparison is not automatically a definitive exclusion.
Goal: match vehicle recalls
Call GET /recalls/vehicles/{vin}. The capability is a series-level match against the documented official registers and carries data-version information. Do not turn a match into a statement that a particular physical vehicle is affected beyond what the response schema says.
Goal: calculate an economic evaluation
Call GET /vin/{vin}/economic-evaluation only with a known full VIN and the documented request parameters. On 202, poll the required statusUrl for GET /vin/economic-evaluation/jobs/{jobId}. Keep the assumptions and returned result character with the evaluation.
Goal: calculate cluster-based VIN Economic Intelligence
Call POST /vin/economic-intelligence (createVinEconomicIntelligence) with a known full VIN, market country, currency, condition and a required Idempotency-Key. This follows the documented VIN-to-vehicle-parts-to-part-cluster Intelligence flow and is distinct from GET /vin/{vin}/economic-evaluation: its final result exposes evaluationId, pipeline coverage, a risk-adjusted portfolio, cluster candidates, confidence, provenance and warnings. The route belongs to a closed, allowlisted commercial pilot and currently returns 503 until VIN Economic Intelligence, approved positive pricing and atomic billing are enabled together. After enablement, a 202 is polled only through GET /vin/economic-intelligence/jobs/{jobId} (getVinEconomicIntelligenceJob); that status operation can continue to return 202 while work is pending. Do not automate acquisition from a result whose confidence, missing evidence or candidate exclusions violate the caller's review policy.
I have an OE number
Goal: validate and normalize the number
Call GET /parts/oe/normalize with the exact query parameter defined by OpenAPI. Use the returned status before reading normalizedOeNumber; the latter is null for every status other than matched.
Do not implement a local uppercase/whitespace rule and call it equivalent. Other OE operations state their own input treatment and may not use the same normalization behaviour.
Goal: retrieve the public base part
Call GET /parts/oe/{oeNumber}. A 200 response is a closed public object containing exactly:
oeNumbernormalizedOeNumbertapiGenArtvdipartfitmentreplacementChainreferencesreferenceNumbers
No confirmed base hit returns 404; an ambiguous input can return 422. The required part object proves that a base record exists, but its public enrichments manufacturer, name and listPrice can each be null. Preserve part.name as the returned string or null. The response always includes tapiGenArt as a valid code or null and vdi as an array of valid full codes or []; they are independent best-effort enrichments, and missing classification data does not invalidate the confirmed base part. tapiGenArt, vdi, fitment, a comparison number or a replacement edge cannot independently create a successful base-part hit.
Interpret the four relationship views separately. fitment contains the available type-level vehicle assignments and can be empty. references[] groups confirmed reference and comparison numbers by manufacturer, while referenceNumbers.oe_oem_reference_numbers[] is the consolidated confirmed list including the confirmed OE number. replacementChain carries confirmed directed from/to edges. Do not derive any of these views from another.
Goal: retrieve aftermarket references
Call GET /parts/oe/{oeNumber}/aftermarket-references. This operation states that it uses the submitted string without OE normalization. Returned references are not installation guarantees. If the business workflow needs a confirmed base part, run the base OE lookup separately rather than treating a reference result as equivalent.
Goal: evaluate price
Use GET /parts/oe/{oeNumber}/price. Preserve whether figures describe new or used ranges and the currency fields exactly as returned. The API result is an evaluation, not a sales-price instruction.
Goal: resolve a part cluster and inspect market intelligence
Call GET /parts/intelligence (resolvePartIntelligence) with oeNumber and, when known, its manufacturer plus kType, NatCode or GenArt context. A required Idempotency-Key represents one business request even though this is a GET. The current closed, allowlisted commercial pilot does not deliver real Intelligence results until approved positive pricing and atomic billing are active. Approved Observed Supply data and the authorised dealer panel are not yet available in production, and adaptive refresh is disabled; without an eligible materialized snapshot, the route returns a documented error instead of starting a refresh. kType, NatCode and GenArt can disambiguate but cannot independently establish cluster identity. On 200, retain the returned clusterId, clusterVersion, scope, timestamps, separated observedSupply, verifiedSales and internalUsage evidence, prices, standtime, trend, scores, confidence and provenance. After refresh enablement, a 202 is polled only through GET /parts/intelligence/jobs/{jobId} (getPartIntelligenceJob). Never map observed listings into verified sales or consume an Opportunity Score without its interval, factors, limitations and confidence.
Goal: optimise an eBay or marketplace article listing
Call GET /parts/oe/{oeNumber}/seo with the target marketplaceId, the content language and vehicleType. This one operation answers every "optimise my eBay article", "which category and item specifics does this part belong in" and "write the listing title for this OE number" goal. There is no separate eBay endpoint: the documented marketplaceId values are the eBay marketplaces EBAY_AT, EBAY_AU, EBAY_BE, EBAY_CA, EBAY_CH, EBAY_DE, EBAY_ES, EBAY_FR, EBAY_GB, EBAY_HK, EBAY_IE, EBAY_IT, EBAY_NL, EBAY_PL, EBAY_SG and EBAY_US, with EBAY_DE as the default. language accepts de, en, fr, es, it, nl, pl and zh.
A successful response carries the listing-ready output for that marketplace and language:
content.ebayTitle— the article title for the eBay listing headline, inside the documented 80-character limit.categoryId— the category identifier for the requested marketplace; for anEBAY_*marketplace, the eBay category. Required-present andnullwhen none is returned.itemSpecifics[]— the article's item specifics as{name, value[]}entries, one name able to carry several values.keywords[]— search terms for the listing and shop search.product—manufacturer,nameandnameAdditionfor product naming.content.title,content.h1,content.metaTitle,content.metaDescription,content.slug,content.bulletPoints— the shop-side SEO text with the documented length limits.
A no-match is the documented, uncharged HTTP 404 PartSeoNoMatchResponse, not a success variant. The operation also has operation-specific live-availability behaviour: 429 seo_live_requests_paused and the optional liveAvailability object state when live enrichment can be requested again. Send no Idempotency-Key. Review the returned copy before publication; it is publication content and never a fitment claim.
Goal: generate publication images
Call POST /vision/part/generate, then poll GET /vision/part/generation-jobs/{jobId} when accepted. This is image generation from an OE number, not evidence that a photographed stock item has the same appearance or condition. Preserve the documented synthetic/disclosure metadata.
Goal: check part recalls
Call POST /recalls/parts with the request positions defined by OpenAPI. Preserve per-position output and register data versions. Do not substitute this for an OE base lookup or vehicle compatibility check.
Goal: retrieve documented vehicle-type assignments
Call GET /parts/oe/{oeNumber} and read fitment[] for the documented reverse OE-to-vehicle-type assignments. The list contains the available assignments and can be empty.
Each result carries an opaque vehicleTypeKey plus its recorded criteria[]; it does not include make/model data and is not a VIN-specific installation guarantee. Criteria are unstructured display text without a documented AND/OR relationship, polarity or executable vocabulary. Preserve them with their key and do not turn them into local compatibility rules. An empty list means no assignment evidence could be returned under the rules above, not that the part fits no vehicle.
API 1.71.0 has no public operation that resolves vehicleTypeKey to make, model or tapiId, and the contract makes no worldwide completeness promise. If the question concerns one known vehicle, call POST /vin/cart-check with the VIN and OE-number position instead. Never substitute aftermarket references, VDI codes, references, referenceNumbers or replacement-chain edges for either evidence scope.
I have a clusterId
Goal: read the current scoped snapshot
Call GET /parts/clusters/{clusterId}/intelligence (getPartClusterIntelligence) with a required Idempotency-Key and explicit market dimensions. Supply clusterVersion when the workflow must pin the cluster composition. On 202, poll GET /parts/intelligence/jobs/{jobId} (getPartIntelligenceJob); keep the returned scope and cluster version attached to the final result.
Goal: compare historical snapshots
Call GET /parts/clusters/{clusterId}/history (getPartClusterIntelligenceHistory) with required from, to, market dimensions and Idempotency-Key. Preserve each point's asOf, clusterVersion, evidence, scores, confidence and provenance.snapshotId. This operation reads materialized history and has no 202 branch: it does not create missing snapshots or start a backfill job.
I have a vehicle registration document
Goal: extract normalized international document fields
For new integrations, call POST /scanner/document/registration/international with the exact fileUrl request property and omit quality or set it to standard. Personal-document extraction offers no other processing level. The response uses the normalized, country-aware field model. Use the vehicle-registration field mapping when mapping printed country codes to canonical response fields.
Use POST /scanner/document/registration when an integration deliberately needs the national response envelope. The deprecated /scanner/registration-document/v2 and /scanner/registration-document paths remain compatibility aliases for existing callers: they do not emit an HTTP redirect and each returns the documented response of its canonical counterpart.
Goal: create a vehicle file in one workflow
Call POST /vehicles/intake. This operation combines registration-document analysis and vehicle matching and may return tapiId for later calls. Use it when the target workflow is vehicle intake, not when the caller only needs OCR fields.
Goal: extract a calculation with its documented equipment
Use POST /scanner/document/calculation with the documented fileUrl and optional quality=standard; no enhanced or maximum level is offered for this personal-document operation. It returns the fixed DocumentCalculationResponse: the previous 11 calculation fields plus required equipment[]. The caller cannot submit an output schema or arbitrary field definition. Preserve equipment[].codes[].value as source strings, including leading zeroes, and keep equipmentKind, sourceSection and sourcePage with every row.
The deprecated POST /scanner/document/extract path is a compatibility path for strict clients of the previous contract. It returns the documented 11 top-level fields and omits equipment; it is not an HTTP redirect. Do not reuse one Idempotency-Key across the canonical and compatibility paths: their response projections differ and the API returns HTTP 409 instead of replaying a differently shaped result.
Goal: extract rich vehicle and equipment data from a vehicle document
Use POST /scanner/document/vehicle with fileUrl, optional quality=standard and includeSensitiveData=false unless there is an authorised, purpose-bound need for named parties, contact, bank, payment or contract details. No enhanced or maximum level is offered for this personal-document operation. Choose this operation instead of calculation extraction when the goal is the rich schemaVersion=1.0 vehicle contract: detailed identifiers, powertrain, transmission, energy, colours, equipment[], warnings and the explicit sensitive-data boundary. Preserve equipment codes as strings exactly as returned, including leading zeroes. Keep equipmentKind (standard, variant, special or null) independent from availability; neither field may be derived from the other. The deprecated /scanner/vehicle-document/extract path is a compatibility alias with the same response contract, not a redirect.
Every response is marked Cache-Control: no-store. With sensitive output disabled, an Idempotency-Key may be used for identical retries. With includeSensitiveData=true, do not send that header: the API rejects it and never stores the sensitive response for replay.
Next step after a detected VIN
Validate the response according to its schema, keep the document extraction record separate from the vehicle lookup result, then follow I have a VIN. A detected string is input to a vehicle lookup, not proof that all document fields describe the resulting technical vehicle type.
I have a parts label image
Choose the smallest operation that meets the goal:
| Goal | Operation | Result handling |
|---|---|---|
| Detect whether and where a part number is visible | POST /scanner/label/basic |
Read only hasPartNumber and where; this response contains no recognized text. |
| Extract part/reference-number candidates | POST /scanner/label/extract-partnumbers |
Confirm candidate numbers through the appropriate OE operation. |
| Extract all detectable label information | POST /scanner/label/extract-all |
Support the documented production and sandbox response variants. |
Never persist an OCR candidate directly as a confirmed OE number. Keep the source image reference, candidate, confirmation result and operator decision distinct in the customer system.
I have one or more images
Select by outcome, not by a generic “AI image” category.
| Desired outcome | Public operation | Boundary |
|---|---|---|
| Read a visible VIN | POST /scanner/vin/extract |
A missing or ambiguous complete VIN can be returned as null; continue only after validation. |
| Describe visible damage | POST /vision/damage/describe |
A description is evidence from submitted images, not a repair decision. |
| Grade visible part quality | POST /vision/part/quality |
Store the grade with the supporting criteria exposed by the schema. |
| Remove a part-photo background | POST /vision/part/remove/bg |
Use found, nullable imageUrl/media/dimensions, coverage, sourcePixelsPreserved and limitations; the response has no generic asset or provenance object. |
| Remove a vehicle-photo background | POST /vision/vehicle/remove/bg |
Same cut-out response boundary; this is an image transformation, not vehicle identification. |
| Classify an end-of-life vehicle | POST /vision/vehicle/elv-classification |
Keep evidence coverage and economic assessment separate from legal disposition. |
| Produce a vehicle condition report | POST /vision/condition-report |
Use for walkaround-condition evidence, not registration-document extraction. |
| Read licence plates | POST /vision/license-plate |
The contract explicitly does not perform keeper lookup, registration validation or authenticity proof. |
| Composite a part into a background | POST /vision/part/composite |
Publication edit with fail-closed identity/redaction checks; not a photo of the actual stock scene. |
| Transfer visible damage to standard views | POST /vision/part/damage-transfer |
Use only for the documented source/target image workflow and preserve synthetic provenance. |
| Redact part identifiers | POST /vision/identifiers/redact |
Redaction is different from reading or validating an identifier. |
All scanner and Vision calls require a documented legal basis and rights for every submitted file and URL. Use only an explicitly approved storage and retention policy.
I have a tapiId
- Use
GET /vehicles/{tapiId}to retrieve documented technical vehicle data. - Use
POST /vehicles/{tapiId}/listingto compose marketplace-ready listing text from the documented vehicle data and request inputs. - Do not send
tapiIdwhere an operation requires a VIN. - Do not treat
tapiIdas the identifier of a physical stock vehicle; keep the integrating system's own vehicle-record ID.
I need to check an OE cart against a VIN
Use this sequence:
VIN selected for the Client
-> POST /vin/cart-check with OE-number positions
-> 200: map final response
-> 202: store jobId + validated statusUrl + nextPollAt
-> GET /vin/cart-check/jobs/{jobId}
-> queued/running: wait according to Retry-After
-> succeeded: map result
-> failed: map embedded job error; do not treat HTTP 200 as success
Store input position IDs so results can be reconciled without relying on array order unless the schema explicitly guarantees order.
I need to separate customers or applications
- Keep the Master client API key in the partner backend.
- For a complete partner onboarding action, use
POST /client/partner-workspacesonly when its combined allowlist/key/sponsorship contract matches the workflow. - Otherwise create a Sub-user with
POST /client/users, then configure its rate limits withPUT /client/users/{clientId}/rate-limitsand add keys withPOST /client/users/{clientId}/keysas required. - Store each plaintext API key exactly once when issued; it cannot be retrieved later.
- After an ambiguous network failure, enter operation-specific
reconciliation_requiredstate and never retry a key-issuing operation blindly.POST /client/userspermits partial reconciliation throughGET /client/users, but the lost raw key still cannot be recovered. The public contract provides neither raw-key recovery forPOST /client/users/{clientId}/keysnor lookup byexternalReferenceforPOST /client/partner-workspaces. - Read usage through
GET /client/usageor, as a Master client,GET /client/users/{clientId}/usage.
The integrating system's Tenant remains its own domain object. Map it to a Client; do not add an undocumented tenant field to API calls.
I need a function that is not listed
Search the published OpenAPI contract by goal, tag, operation ID and path. If no matching operation exists under OpenAPI paths, the capability is not part of API 1.71.0. Do not fabricate a call.