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

  1. Call GET /vin/{vin}/vehicle with the request parameters documented for the customer contract.
  2. If the response requires a browser redirect, follow the documented redirect-session flow; otherwise consume the direct result.
  3. Read tapiId, the returned selection value and the documented vehicle data from the success response.
  4. Persist the VIN and tapiId separately; tapiId represents the matched technical vehicle type, not the individual physical car.
  5. Continue with GET /vehicles/{tapiId} for technical vehicle data or POST /vehicles/{tapiId}/listing for listing text when needed.

Treat the numeric selection value as an opaque contract value. Do not infer capabilities, suppliers or data provenance from it.

  1. Call GET /vin/{vin}/parts with a full VIN and the request parameters documented for the customer contract.
  2. Keep the optional numeric selection consistent for the same VIN. A conflicting value returns 409 vin_provider_mismatch.
  3. On 200, map parts[], including each required tapiGenArt and vdi field, plus matchLevel, provider and the returned tapiId according to the schema. Preserve vdi=[] as the complete value for a position without a valid mapping.
  4. On 202, persist the job and poll the required full statusUrl with GET /vin/parts/jobs/{jobId} after Retry-After. Compare Location with that documented URL and quarantine a mismatch rather than resolving its current root-relative example against the API origin.
  5. Treat matchLevel as 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:

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:

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

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

  1. Keep the Master client API key in the partner backend.
  2. For a complete partner onboarding action, use POST /client/partner-workspaces only when its combined allowlist/key/sponsorship contract matches the workflow.
  3. Otherwise create a Sub-user with POST /client/users, then configure its rate limits with PUT /client/users/{clientId}/rate-limits and add keys with POST /client/users/{clientId}/keys as required.
  4. Store each plaintext API key exactly once when issued; it cannot be retrieved later.
  5. After an ambiguous network failure, enter operation-specific reconciliation_required state and never retry a key-issuing operation blindly. POST /client/users permits partial reconciliation through GET /client/users, but the lost raw key still cannot be recovered. The public contract provides neither raw-key recovery for POST /client/users/{clientId}/keys nor lookup by externalReference for POST /client/partner-workspaces.
  6. Read usage through GET /client/usage or, 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.