Capability map

This page maps an integration goal to the public tapinomahub operation that implements it. It is derived only from the released OpenAPI 3.1 contract (version 1.71.0). The OpenAPI contract remains authoritative for full schemas, status codes and examples.

Every operation below uses apiKeyAuth: send the API key in the server-side X-Api-Key header. A capability is not evidence that the authenticated Client is entitled to use it; handle the documented authentication, allowlist, billing and rate-limit responses for the selected operation.

1. Check API reachability

Use when: a server-side integration needs to confirm that the authenticated API endpoint is reachable.

Do not use when: the integration needs to verify a business-data source, a VIN, a part, credit sufficiency or entitlement. This operation performs no business-data query.

Inputs: no business input; only the authenticated request.

Outputs: status and service in PingResponse.

operationId Method and path Selection note
getSystemStatus GET /ping Technical API availability only.

Next steps: after status="ok", call the operation required by the business workflow. No reusable identifier is produced.

2. Administer Sub-users, keys and isolated workspaces

Use when: a Master client must list or create Sub-users, change a managed Sub-user, issue a key, replace its rate limits, or provision a Client, key and endpoint allowlist from one external reference.

Do not use when: the goal is to process vehicle, part, document or image data. Do not use a single Sub-user as an undocumented substitute for multiple isolated customer accounts.

Inputs: name is required to create a Sub-user. Updates and key creation require the path clientId; key creation optionally accepts label. Rate-limit replacement requires rateLimits. Partner provisioning requires name, externalReference and endpointKeys, with optional sponsorship, applicationLabel and rateLimits. Where used, defaultProviderId must match its documented enum.

Outputs: listClientUsers returns users[], createClientUser returns user and apiKey, and updateClientUser returns user; each user is a ClientUser whose Client identifier is id. replaceClientUserRateLimits returns rateLimits[] of type RateLimit, which adds id, clientId and createdAt to the fields of RateLimitInput. Key-issuing responses contain apiKey.key in plaintext once. Partner provisioning returns workspace.id, workspace.externalReference, apiKey, allowlist and sponsorshipGrant, which is always present and null when no sponsorship was requested.

operationId Method and path Selection note
listClientUsers GET /client/users List the authenticated Master client's managed Sub-users.
createClientUser POST /client/users Create one Sub-user and its initial key.
updateClientUser PATCH /client/users/{clientId} Change permitted fields or active status.
createClientUserApiKey POST /client/users/{clientId}/keys Issue another key for an existing managed Sub-user.
replaceClientUserRateLimits PUT /client/users/{clientId}/rate-limits Replace, rather than merge, the submitted rate-limit configuration.
createPartnerWorkspace POST /client/partner-workspaces Provision a Client, one key, an allowlist and optional sponsorship in one call.

Next steps: store a newly returned apiKey.key immediately in a server-side secret store; it is not returned again. Send the returned user.id (in the list: users[].id) as the path clientId of the later managed-Client operations. Do not use workspace.id in a {clientId} path unless the public contract explicitly establishes that relationship. After a timeout, reconcile per operation instead of retrying blindly. Repeat updateClientUser or replaceClientUserRateLimits unchanged with the same optional Idempotency-Key: keys are scoped per Client for 24 hours, a successful repeat returns the same result without another execution, and a repeat returns 409 idempotency_request_in_progress while the first call is running or 409 idempotency_result_unavailable when its result cannot be retrieved. createClientUser, createClientUserApiKey and createPartnerWorkspace reject that header with 400 idempotency_key_not_supported: check listClientUsers before repeating createClientUser, and expect 409 workspace_reference_exists instead of a second workspace when createPartnerWorkspace is repeated with the same externalReference. No public operation returns a lost raw key again.

3. Inspect usage, plans and sponsorship

Use when: a Client needs its balance or consumption, a Master client needs a managed Sub-user's consumption, or a sponsor and beneficiary need to inspect or control documented tapinomahub cost coverage.

Do not use when: the workflow needs a price quote for a part, a VIN economic evaluation or a general contract-pricing calculation. A sponsorship changes the documented billing route; it does not transfer the beneficiary's usage or VIN entitlement.

Inputs: own-credit, own-usage, plan and list operations need no business input. Managed usage needs clientId. Issuing or replacing a grant needs path grantReference (1–100 characters from A-Z, a-z, 0-9, ., _, :, -) plus beneficiaryClientId and endpointKeys (1–50 unique keys); optional are channels (only hub, the default), startsAt (immediate when omitted), endsAt (exclusive), partnerTermsAllowed and beneficiaryMonthlyCapCents (null means no limit). Omitting partnerTermsAllowed or beneficiaryMonthlyCapCents keeps the existing setting; setting partnerTermsAllowed back to false drops a choice the beneficiary already made. Revocation needs grantReference. A beneficiary's billing choice needs grantReference, mode=own|partner, and sponsorClientId when the reference is ambiguous.

Outputs: CreditStatus exposes clientId, billingMode (own or partner), balanceCents, balance, currency, creditLimitCents and availableCents; with billingMode=partner the amounts and currency are null; UsageStatus exposes clientId, balance, period, plans and endpoints. Plan responses expose visible standard and custom plans. Sponsorship responses expose sponsorshipGrant or sponsorshipGrants[], including reference, parties, covered endpoint keys, dates, active state and terms fields.

operationId Method and path Selection note
getClientCredits GET /client/credits Read the authenticated Client's balance and billing mode.
getClientUsage GET /client/usage Read the authenticated Client's balance, plan consumption and endpoint usage.
getClientUserUsage GET /client/users/{clientId}/usage Read usage for a managed Sub-user.
listPlans GET /client/plans List plans visible to the authenticated Master client.
listSponsorshipGrants GET /client/sponsorship-grants List active and historical grants issued by the caller.
listReceivedSponsorshipGrants GET /client/sponsorship-grants/received List grants received by the caller.
upsertSponsorshipGrant PUT /client/sponsorship-grants/{grantReference} Idempotently issue or replace the grant under the sponsor-selected grantReference.
revokeSponsorshipGrant DELETE /client/sponsorship-grants/{grantReference} Stop the grant for new requests; existing results and entitlements remain.
chooseSponsorshipBillingMode PUT /client/sponsorship-grants/received/{grantReference}/billing-mode Let the beneficiary choose own or an authorised partner mode.

Next steps: use returned endpoint keys when configuring allowlists or grants. Branch on stable fields such as billingMode, active and the documented error code, not on human-readable messages. Keep the sponsor-selected grantReference; response objects expose it as reference.

4. Start a browser-guided VIN flow

Use when: the numeric data route required by the public contract must run through the tapinomahub browser interface, or the user must complete a partial VIN of 3–17 permitted characters.

Do not use when: the caller expects vehicle data in the session-creation response, wants to expose its API key in a browser, or needs a direct server-to-server response from another documented numeric route.

Inputs: JSON vin and an absolute HTTPS returnUrl without credentials or a fragment; optional state is at most 512 characters. The server creates the session with its API key.

Outputs: the creation response contains only redirectUrl and expiresAt. The later redirect to returnUrl carries status=completed, tapiId and optional unchanged state, or status=cancelled and optional unchanged state.

operationId Method and path Selection note
createVinRedirectSession POST /vin/redirect-sessions Create a short-lived, single-use browser session.

Next steps: redirect the user's browser to redirectUrl. On a completed callback, use tapiId with GET /vehicles/{tapiId} or POST /vehicles/{tapiId}/listing. The callback does not return the VIN completed in the browser: keep the caller's original input only as such, and enter any VIN-parts flow only when a full 17-character VIN has been confirmed independently. On cancellation, there is no tapiId to consume.

5. Retrieve vehicle data directly from a VIN

Use when: the caller has authority to process a VIN and needs the documented direct vehicle comparison, optional equipment, colours or technical details.

Do not use when: the selected numeric route requires the browser flow, or when incomplete=true would be incorrectly presented as an exact single-vehicle resolution.

Inputs: path vin; optional country (default de), provider (1, 2 or 3; default 1) and the booleans includeEquipments, includeColors and includeTechnical (each default true). An invalid country or provider returns 400 invalid_country or 400 invalid_provider.

Outputs: VinVehicleResponse includes vin, stable tapiId, numeric provider, incomplete, vehicle hierarchy and the requested optional data groups.

operationId Method and path Selection note
getVehicleByVin GET /vin/{vin}/vehicle Direct lookup for the numeric routes the endpoint permits; the browser-only value returns 409 redirect_required.

Next steps: retain tapiId for GET /vehicles/{tapiId} or POST /vehicles/{tapiId}/listing. If a later GET /vin/{vin}/parts includes the optional numeric selection, use the documented value consistently; a conflicting explicit value returns 409 vin_provider_mismatch.

Use when: the caller needs the parts assigned to a VIN, or needs to compare 1–30 OE-number strings with that VIN at type or vehicle level.

Do not use when: an OE base record, OE normalization, a mapping for one already-known OE number, the general VDI catalogue or general aftermarket references are the actual goal. A cart result with fits=false is not a definitive exclusion when complete=false.

Inputs: parts lookup uses path vin plus optional country and numeric provider as documented for the operation. Cart checking uses JSON vin (exactly 17 characters matching ^[A-HJ-NPR-Z0-9]{17}$), mode=type|vehicle, optional country (default de) and oeNumbers[] with 1–30 strings of 1–64 characters each. Status operations consume the jobId from the corresponding 202 only.

Outputs: an immediate parts response exposes vin, nullable tapiId, numeric provider, matchLevel (vehicle_specific_best_available, vehicle_type_candidates or vehicle_specific_unverified), allCategorySigns, missingCategories (a non-empty list means the parts list is incomplete) and parts[]; every returned part has exactly one tapiGenArt and the required vdi array of confirmed full VDI 4081 codes. vdi=[] is the complete field value when no valid mapping is available for that position. A successful asynchronous job exposes the same part shape under result.parts[]. An immediate cart response exposes vin, mode, complete and ordered results[] with oe and fits. A 202 response exposes jobId, status (queued, running, succeeded or failed), statusUrl, the Retry-After header, retryAfterSeconds while the status is queued or running, and later either result or error; the job schemas allow only provider=1 for parts lookups and only mode=vehicle for cart checks.

operationId Method and path Selection note
getPartsByVin GET /vin/{vin}/parts Return the result immediately or accept the documented asynchronous route.
getVinPartsJob GET /vin/parts/jobs/{jobId} Poll only a VIN-parts job.
checkVinCart POST /vin/cart-check Compare the ordered OE cart at the requested level.
getVinCartCheckJob GET /vin/cart-check/jobs/{jobId} Poll only with the jobId and statusUrl returned by the cart-check operation.

Next steps: on 202, validate and follow the required full statusUrl after Retry-After; compare Location and quarantine a mismatch instead of constructing a URL from it. Do not resubmit the business request merely because it is asynchronous. On succeeded, consume result; on failed, branch on error.code: vehicle_not_found is a no-result outcome, vin_service_unavailable a technical failure. Preserve every required parts[].vdi array as returned, including []; an empty array is not a pending state. A returned parts[].number can be supplied to OE operations, but a nullable number and every technical or commercial conclusion still require the selected operation's documented validation.

7. Create a VIN economic evaluation

Use when: the caller needs the documented economic evaluation for a VIN, including parts-revenue potential, dismantling ranking and a vehicle purchase recommendation.

Do not use when: the goal is a binding purchase, sale or price guarantee, or when the required numeric selection is not accepted by this operation.

Inputs: path vin; every query parameter is optional: country (default de), provider (only 1, the default), condition=used|new (default used), vehicleType=car|motorcycle (default car), maxPricedParts from 1 to 100 (default 100), recoveryRate from 0.05 to 1 (default 0.5) and costPerPart from 0 to 1000 (default 0), the assumed cost per priced part in EUR for removal, storage and shipping. recoveryRate and costPerPart feed the purchase recommendation.

Outputs: VinEconomicEvaluationResponse always contains vin, provider (1), matchLevel (vehicle_specific_best_available), currency (EUR), condition, vehicleType, assumptions (maxPricedParts, recoveryRate, costPerPartEur, priceBasis=min), coverage, revenuePotential (min, average, max), purchaseRecommendation.goodPurchasePriceEur and parts[], each part with rank, number, amount and pricing; tapiId, warnings[] and liveAvailability are optional. A 202 exposes a type-specific job; its successful result has the same evaluation shape.

operationId Method and path Selection note
getVinEconomicEvaluation GET /vin/{vin}/economic-evaluation Start or retrieve the evaluation.
getVinEconomicEvaluationJob GET /vin/economic-evaluation/jobs/{jobId} Poll only the economic-evaluation job.

Next steps: on 202, poll the validated full statusUrl after Retry-After. On succeeded, result contains the complete evaluation; on failed, error.code is vehicle_not_found (no-result outcome), vin_service_unavailable (technical failure), or market_pricing_unavailable (no usable market prices for the evaluation), and any charge for the original request has been refunded automatically. Keep the returned assumptions and coverage with any policy-permitted business use of the figures; do not detach the recommendation from its warnings or result character.

8. Validate an OE number and retrieve the confirmed base part

Use when: the caller needs an explicit normalization decision, or a confirmed OE base record with its tapinomahub GenArt, VDI mappings, documented type-level fitment, grouped comparison references and directed replacement chain.

Do not use when: a scanner reading alone is being treated as a catalogue match; tapinomahub GenArt or VDI is being used to create a base-part match independently; or a type-level assignment is being treated as a VIN-specific installation guarantee.

Inputs: normalizeOeNumber takes query oeNumber (1 to 128 characters) and optional query manufacturer (1 to 100 characters). getOePart takes path oeNumber (1 to 128 characters) and optional query manufacturer (1 to 100 characters). Neither operation accepts an Idempotency-Key (400 idempotency_key_not_supported).

Outputs: normalization returns exactly the required fields version, input, nullable manufacturer, status (matched, unresolved, ambiguous or invalid), valid, reasons[], lookupKey, nullable normalizedOeNumber, nullable matchRule, nullable confidence (0 to 1), equivalentOeNumbers[], equivalentOeNumberCount, equivalentOeNumbersTruncated and knownCandidates[] as {value, rule, manufacturers[]} entries. A successful base lookup returns exactly oeNumber, normalizedOeNumber, tapiGenArt, vdi, part, fitment, replacementChain, references and referenceNumbers; an OE number for which no part is known returns 404 oe_part_not_found, and an OE number that cannot be resolved uniquely returns 422 ambiguous_oe_number. The required part object proves that the base record exists, while its public manufacturer, name and listPrice values can each be null. Preserve part.name as the returned string or null. The required tapiGenArt field contains a valid classification or null; the required vdi array contains only valid full codes and is [] when none is available. The two classifications are independent best-effort enrichments: absence of either one does not invalidate the confirmed base part or suppress the other. fitment[] contains the available {vehicleTypeKey, criteria} assignments and can be empty. criteria[] is a list of unique, non-empty free-text strings and can itself be empty; it is not an executable rule language. references[] groups confirmed reference and comparison numbers as {manufacturer, numbers}. referenceNumbers contains exactly oe_oem_reference_numbers[], the consolidated confirmed numbers including the confirmed OE number. Keep both reference views separate from the directed replacementChain; do not derive one from another.

operationId Method and path Selection note
normalizeOeNumber GET /parts/oe/normalize Obtain an explicit match state; read normalizedOeNumber only when status=matched.
getOePart GET /parts/oe/{oeNumber} Retrieve the closed confirmed base-part object.

Next steps: preserve the submitted oeNumber and returned normalizedOeNumber separately. Use the confirmed number for further OE-number inputs. Preserve nullable part.name and tapiGenArt exactly as returned, and do not fill either from another field. In a validated 200, treat empty vdi and fitment lists as absence of returned mappings, not as global negative proof. Keep vehicleTypeKey opaque. Follow replacementChain as directed edges rather than assuming bidirectional equivalence; use POST /vin/cart-check when one specific VIN must be checked.

9. Enrich or evaluate an OE number

Use when: the caller needs aftermarket references or an indicative price evaluation for an OE number. Marketplace and eBay article content has its own capability below.

Do not use when: the caller needs proof of installation on a vehicle, a confirmed base-part response, or a binding commercial price. Aftermarket references are not compatibility guarantees.

Inputs: both operations use path oeNumber and must not receive an Idempotency-Key (400 idempotency_key_not_supported). The aftermarket-reference lookup additionally accepts limit (1 to 500) and offset (at least 0, only together with limit); without limit the complete list is returned, and each page is a separate call that is charged like a call. Price evaluation accepts condition (new or used, default used), currency (ISO 4217 code, default EUR) and vehicleType (car or motorcycle, default car).

Outputs: references return oeNumber, aftermarketReferences[] as {partNumber, normalizedPartNumber, manufacturer} entries (manufacturer can be null) and count, which is the total in every response; the optional page object carries limit, offset, returned and hasMore. Price evaluation returns the required oeNumber, condition, currency, vehicleType, result (priced or no_listings_found), the ranges new and used as {min, max, average} and priceRecommendation as {min, max, average, confidence} with confidence HIGH, MEDIUM or LOW. Read the figures only through result: under no_listings_found every value is 0 and must not be read as a market price. If nothing could be measured at all, the endpoint answers with an error status instead of a result; 404 oe_part_not_found is documented as no available price data. There is no count of evaluated offers in the response.

operationId Method and path Selection note
getOeAftermarketReferences GET /parts/oe/{oeNumber}/aftermarket-references Paginated reference candidates; an empty list is a successful result.
getOePrice GET /parts/oe/{oeNumber}/price Indicative price evaluation with condition-specific ranges and recommendation.

Next steps: independently verify references and price evaluations for the intended technical and commercial use. For article, listing or shop content, continue with the marketplace and eBay optimisation below.

10. Use part-cluster and VIN Economic Intelligence

Use when: the caller needs market evidence and uncertainty for a versioned part cluster rather than a value for one isolated OE number, wants to compare historical cluster snapshots, or wants to aggregate eligible cluster intelligence for one VIN.

Do not use when: a listing is to be treated as a verified sale, a score without its confidence and evidence scope would drive an automatic decision, or a binding purchase, sale, compatibility or price guarantee is required. These operations complement rather than replace the single-OE price evaluation and the existing VIN economic evaluation.

Inputs: cluster resolution requires at least oeNumber (3 to 80 characters) or aftermarketNumber (3 to 120 characters; an aftermarket, MPN or GTIN reference), otherwise it returns 422 identifier_required; oeManufacturer and aftermarketManufacturer name the namespace of the respective number, and kType, natCode and genArt are optional disambiguation context that never anchors a cluster on its own. More than one matching cluster returns 422 ambiguous_cluster. Current and historical reads require the returned UUID clusterId; the current read can also pin clusterVersion. Resolution, current read and history share marketCountry (two upper-case letters, default DE), currency (three upper-case letters, default EUR), condition (new, remanufactured, used or unknown, default used) and minimumEvidence (any, directional, usable or strong, default any; a higher tier that is not reached returns 422 insufficient_evidence). Resolution and current read also accept windowDays (30, 60, 90, 180 or 365, default 90) and asOf as a historical cutoff; without asOf the most recent eligible snapshot is used. An unknown or repeated query parameter returns 400 invalid_query_parameter. Cluster resolution and current reads accept freshnessPolicy (allow_stale, refresh_if_stale or require_fresh, default refresh_if_stale); history reads materialized points only and does not trigger refreshes, so it does not accept that parameter, and it accepts neither windowDays nor asOf. History additionally requires the dates from and to (an invalid range returns 422 invalid_history_window) and accepts granularity (day, week or month, default week) and restated (default false; pilot points are marked restated=false). VIN Economic Intelligence takes an application/json body of at most 32 KiB. The contract lists vin (17 characters matching ^[A-HJ-NPR-Z0-9]{17}$), marketCountry, currency and condition as required, and accepts asOf, minimumEvidence, freshnessPolicy (for VIN aggregation only allow_stale evaluates expired snapshots), maxCandidates (1 to 100, default 100), economicProfileId (reserved; the pilot does not use it and marks it as economic_profile_pending) and includeInsufficientCandidates (default true). The scope.windowDays of a VIN result is always 90. Every initiating Intelligence operation declares a required Idempotency-Key of 16 to 100 characters from A-Z, a-z, 0-9, _ and -, including its three GET operations; reusing a key for a different business scope returns 409 idempotency_key_conflict, and a replay is marked with X-Tapinoma-Idempotent-Replay: true. The two status operations take only their family-specific jobId and accept neither that header nor query parameters. The commercial pilot remains closed until approved positive pricing and atomic billing are active; no real Intelligence result is delivered while either gate is missing.

Current pilot boundary: access to these six operations is limited to allowlisted pilot accounts with a verified email address. They accept X-Api-Key or the __Host-tapinomahub_session cookie of a verified first-party session; a session-authenticated POST also needs X-CSRF-Token. An API key outside the allowlist receives 401 authentication_required, a session outside it 403 market_intelligence_not_enabled. Approved Observed Supply data and the authorised dealer panel are not yet available in production; adaptive refresh and VIN Economic Intelligence are disabled. While billing is not active, all six operations answer 503 market_intelligence_billing_unavailable. Beyond that gate, part operations read only eligible materialized snapshots already present: for cluster resolution and current reads without asOf, a missing eligible snapshot, or a stale snapshot under freshnessPolicy=require_fresh, returns 422 refresh_unavailable, while allow_stale and refresh_if_stale return the stale snapshot with the warning stale_snapshot. VIN Intelligence answers 503 market_intelligence_vin_not_enabled until it is enabled. Without sufficient evidence, scores remain null or publishable=false.

Outputs: a cluster result with apiVersion market-intelligence-v1 contains requestId, status (scored, indicative or insufficient_evidence), asOf, validUntil, scope, cluster (clusterId, clusterVersion, canonicalLabel, identityConfidence, identifiers, dimensions), evidence with the separate blocks observedSupply, verifiedSales and internalUsage, prices (marketPrice with amountMinor, and recommendedRange with floorMinor, targetMinor and ceilingMinor, each a nullable integer), standtime, trend, scores (demand, liquidity, competition, priceConfidence and opportunity, each value 0 to 100 or null), confidence, provenance and warnings[]. Preserve the top-level confidence with its level, publishable, caps[] and missingEvidence[], and prices.recommendedRange.publishable, with every score. History returns clusterId, scope, granularity and points[]; every point keeps the clusterVersion and provenance (including scoreVersion) that applied at the time. VIN Economic Intelligence returns requestId, evaluationId, status (scored, partial or insufficient_evidence), asOf, scope, pipeline, portfolio, candidates[] (each with clusterId, clusterVersion, status valued, indicative, insufficient_evidence or excluded, and nullable exclusionReason), confidence, provenance and warnings[]. With the default includeInsufficientCandidates=true, candidates with status excluded or insufficient_evidence stay in candidates[]; with false they are omitted from the array, while portfolio and coverage values still count them. A 202 returns requestId and jobId (identical in the pilot), status (queued or running), reason (snapshot_missing, stale_snapshot, vehicle_parts_pending or refresh_pending), requestedAt, optional nullable estimatedReadyAt and statusUrl, with the headers Location and Retry-After, instead of a final result.

operationId Method and path Selection note
resolvePartIntelligence GET /parts/intelligence Resolve OE or aftermarket input to one versioned cluster and return its scoped Intelligence result.
getPartClusterIntelligence GET /parts/clusters/{clusterId}/intelligence Read current or explicitly versioned Intelligence for a known cluster.
getPartClusterIntelligenceHistory GET /parts/clusters/{clusterId}/history Read the materialized history for one cluster and market scope.
getPartIntelligenceJob GET /parts/intelligence/jobs/{jobId} Poll only a refresh accepted by a part-cluster Intelligence operation.
createVinEconomicIntelligence POST /vin/economic-intelligence Aggregate eligible part-cluster evidence into a VIN-level economic portfolio.
getVinEconomicIntelligenceJob GET /vin/economic-intelligence/jobs/{jobId} Poll only the VIN Economic Intelligence job returned by the create operation.

Next steps: after the corresponding pilot feature has been enabled, a 202 requires retaining the exact job family and polling its documented statusUrl after Retry-After; never move a jobId between the part and VIN paths. With a final result, retain clusterId, clusterVersion, scope, asOf, evidence separation, score version, confidence and warnings together. Do not substitute the older single-OE or VIN-evaluation response schemas for these cluster-based contracts.

11. Optimise a marketplace or eBay article listing

Use when: a confirmed OE number is to be published as an article, offer or listing — on eBay in particular, or in the caller's own shop — and the article needs a ready-to-use title, the matching marketplace category, structured item specifics, search keywords and on-page SEO text. This is the capability behind every "optimise my eBay listing", "which eBay category and item specifics belong to this part" or "write the article title for this OE number" goal. There is no separate eBay endpoint; the marketplace is selected with marketplaceId.

Do not use when: the caller needs a compatibility or installation statement, a confirmed base part, a price, or an unreviewed automatic publication. The enrichment produces publication content, not fitment evidence, and the result is to be checked for accuracy and permissibility before it goes live.

Inputs: path oeNumber, plus optional marketplaceId, language and vehicleType. marketplaceId selects the target marketplace; its documented enum 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, and the default is EBAY_DE. language is de, en, fr, es, it, nl, pl or zh (ISO 639-1); a language the selected marketplace does not support returns 400 unsupported_marketplace_language. vehicleType is car or motorcycle, default car. A query parameter the operation does not accept returns 400 unsupported_query_parameter. The operation is a GET and must not receive an Idempotency-Key (400 idempotency_key_not_supported).

Outputs: a successful 200 contains the nine required fields oeNumber, marketplaceId, language, vehicleType (car or motorcycle), categoryId, product, content, keywords and itemSpecifics and no other field except an optional liveAvailability object, which the published 200 schema additionally permits; paused live enrichment is signalled by the X-Tapinoma-Live-Available-At header, which states the earliest time at which paused live processing should be retried, and by 429 seo_live_requests_paused. Mapped to the fields of a marketplace article:

Response field Use in the listing
content.ebayTitle The article title for the eBay listing headline, composed for the selected marketplace and language and kept within the documented maximum of 80 characters.
categoryId The category identifier for the requested marketplaceId; for an EBAY_* marketplace, the eBay category the article belongs in. The field is required-present and is null when no category is returned.
itemSpecifics[] The structured item specifics of the article as {name, value[]} entries; one name can carry several values.
keywords[] Search terms for the listing and for shop search.
product manufacturer, name and nameAddition for the article's product naming; manufacturer and nameAddition can be null, while name is always a string and can be empty.
content.title, content.h1, content.metaTitle, content.metaDescription, content.slug, content.bulletPoints Shop SEO text; all seven content fields including ebayTitle are required. title, h1 and metaTitle have at most 80 characters each and metaDescription at most 160; slug matches ^[a-z0-9]+(?:-[a-z0-9]+)*$; bulletPoints[] holds at most five strings of at most 160 characters each.

A no-match is answered with 404 and error code seo_no_exact_match; the body carries a fixed message and echoes oeNumber (normalized and upper-cased), marketplaceId, language and vehicleType. That is a documented no-match answer rather than a malfunction; the contract marks this case as not billed, and the 404 response refers its commercial treatment to the terms shown when ordering and agreed in the contract. A 429 carries either rate_limit_exceeded or client_request_in_progress, or seo_live_requests_paused with the required liveAvailability object: status PAUSED, reason RATE_LIMIT_REACHED, availableAt (date-time) and retryAfterSeconds (1 to 86400). X-Tapinoma-Live-Available-At states the earliest retry and Retry-After the minimum wait in seconds.

operationId Method and path Selection note
getPartSeo GET /parts/oe/{oeNumber}/seo Marketplace and eBay article optimisation for one OE number: title, category, item specifics, keywords and shop SEO text.

Next steps: publish through the shop or marketplace system, which remains the system of record for SKU, stock, condition, price and offer state. Review the generated copy before publication and keep categoryId, itemSpecifics[] and the returned title with the article record so that a later regeneration can be compared against it. Never present the enrichment as proof that the part fits a vehicle: documented vehicle-type assignments come from fitment[] of GET /parts/oe/{oeNumber}, a check against one specific VIN comes from POST /vin/cart-check, and both results must be independently verified before use.

12. Extract vehicle-registration, vehicle-order or general document data

Use when: the input is a registration-document image/PDF, a vehicle order, purchase contract, repair cost calculation, appraisal, invoice, vehicle configuration or another supported automotive document and structured fields are needed.

Do not use when: a label, a standalone VIN photograph, or a complete vehicle-intake workflow is the actual input. Do not assume every field is readable or non-null.

Inputs: national registration accepts fileUrl or deprecated imageUrl; international registration additionally accepts deprecated imageURL. New integrations use fileUrl. Calculation-, purchase-contract and vehicle-document extraction require fileUrl. Vehicle-document extraction also accepts includeSensitiveData, which defaults to false. These personal-document operations accept only quality=standard.

Outputs: the closed international response has eight required fields: format (fixed value tapinoma.vehicle-registration.v2), document, registration, holder, inspection, vehicle, fields[] and warnings[]; vehicle.vin is nullable. The national registration operation and its legacy path return the same closed {status:"ok",data} envelope in production and sandbox; data always contains registrationNumber, documentNumber, issuingAuthority, issuedDate, owner, inspection, vehicle, technicalDetailsRaw, codesAndNotes, rawTextLines and notes. owner, inspection, vehicle, technicalDetailsRaw and codesAndNotes are always objects; every other value, including every field inside those objects, is nullable, and vehicle.tireSizes may also be an empty list when no tyre size was read. Calculation extraction returns exactly the previous 11 top-level calculation fields plus required equipment[]. Its deprecated /scanner/document/extract alias deliberately retains the previous 11-field response without equipment for strict existing clients. Purchase-contract extraction returns PurchaseContractExtractionResponse with schemaVersion="1.0", document, seller, buyer, vehicle, purchase, handover, condition, signatures and warnings. It reads explicitly stated information; unknown values remain null and absent lists remain empty. Signature presence is not a verification of authenticity or legal validity. Rich vehicle-document extraction instead returns the closed schemaVersion=1.0 structure with document, a detailed vehicle block, equipment[], sensitiveData and fixed warnings[] codes. Every equipment item keeps equipmentKind separate from availability, and every codes[].value is a string whose leading zeroes and printed formatting must be preserved.

operationId Method and path Selection note
extractRegistrationDocument POST /scanner/document/registration National registration-document contract: production and sandbox both return {status,data} with lowerCamelCase fields.
extractRegistrationDocumentLegacyPath POST /scanner/registration-document Deprecated compatibility alias of extractRegistrationDocument; same request and response without an HTTP redirect.
extractInternationalRegistrationDocument POST /scanner/document/registration/international Normalized international structure with detected fields and warnings.
extractInternationalRegistrationDocumentLegacyPath POST /scanner/registration-document/v2 Deprecated compatibility alias of extractInternationalRegistrationDocument; no HTTP redirect.
extractCalculationDocument POST /scanner/document/calculation Calculation-oriented 12-field extraction including equipment[].
extractPurchaseContract POST /scanner/document/purchase-contract Read explicit seller, buyer, vehicle, purchase price, payment, handover, warranty and signature-presence information from a purchase contract. No legal or signature validation.
extractDocument POST /scanner/document/extract Deprecated compatibility path with the documented 11-field response and no equipment; no HTTP redirect.
extractVehicleDocument POST /scanner/document/vehicle Extract vehicle, identifier and equipment data from supported vehicle documents.
extractVehicleDocumentLegacyPath POST /scanner/vehicle-document/extract Deprecated compatibility alias of extractVehicleDocument; no HTTP redirect.

Next steps: choose the canonical path for every new integration. The four deprecated paths are compatibility aliases, not 307/308 redirects, so callers retain the POST body and are never charged by a second hop. The national registration, international registration and rich vehicle pairs share idempotency across their canonical and legacy paths. Calculation is intentionally different: the canonical response has 12 fields while the legacy response has 11, so reusing one Idempotency-Key across those two paths returns HTTP 409 idempotency_key_conflict; use the canonical path for a new business action and reuse a key only on the same response contract. If a non-null VIN was extracted, it can start a VIN capability; if VIN is null, do not invent or pad it. Keep source values and warnings with normalized document fields. For rich vehicle-document extraction, treat equipmentKind=standard|variant|special|null and availability as independent axes; do not infer one from the other. Preserve both codes[].value and nullable normalizedValue, especially leading-zero codes. Both vehicle-document paths declare Cache-Control: no-store on every documented response (200, 400, 401, 402, 403, 409, 429, 500, 503); the registration and calculation operations declare no Cache-Control header. The purchase-contract operation accepts an HTTPS fileUrl without credentials for PDF, JPEG, PNG or WebP (PDF at most 14,000,000 bytes; images at most 7,000,000 bytes). All its responses carry Cache-Control: no-store; it rejects Idempotency-Key with HTTP 400 idempotency_key_not_supported. For rich vehicle-document extraction, use an Idempotency-Key only while includeSensitiveData is omitted or false; with includeSensitiveData=true the API rejects that header with HTTP 400 idempotency_key_not_supported.

13. Read labels or a photographed VIN

Use when: the input is a part-label image, markings on a part, or an image expected to show one complete VIN.

Do not use when: OCR output is expected to establish an OE catalogue match, or a partial/uncertain VIN should be guessed. hasPartNumber=false does not prove that no number exists in the source image.

Inputs: a publicly accessible imageUrl (format: uri) and optional quality=standard|enhanced|maximum, default standard; the part-number operation explicitly accepts absolute HTTP or HTTPS URLs, and operation-specific fetch restrictions apply. Label-details also accepts deprecated imageURL as documented.

Outputs: basic label detection returns hasPartNumber and where. Part-number extraction returns partNumbers[] in both environments. Detailed extraction always returns {status,data}; business fields such as primaryPartNumber and otherPartNumbers are omitted when not detected. VIN extraction returns nullable vin and never guesses an incomplete value.

operationId Method and path Selection note
extractLabelText POST /scanner/label/basic Determine whether a plausible number is present and where.
extractLabelPartNumbers POST /scanner/label/extract-partnumbers Return normalized number readings.
extractLabelDetails POST /scanner/label/extract-all Return all sufficiently confident structured label findings.
extractVinFromImage POST /scanner/vin/extract Return a complete, unambiguous 17-character VIN or null.

Next steps: send a candidate part number to GET /parts/oe/normalize or GET /parts/oe/{oeNumber} before treating it as an OE fact. Send a non-null VIN to the selected VIN flow. Production and sandbox share one 200 response schema per operation, so one typed client serves both environments; for part-number and detailed extraction the contract states that the named examples differ only in their example values.

14. Translate one part designation

Use when: exactly one individual part designation must be rendered in English, French, Spanish and Italian.

Do not use when: the input is a title, heading, description, sentence, list, offer text or multiple designations.

Inputs: required query sourceLanguage (non-empty string, maxLength: 20) and required query text (non-empty string, maxLength: 1000). A missing or empty sourceLanguage returns HTTP 400 source_language_required, a missing or empty text returns 400 text_required; over-long values return 400 source_language_too_long or text_too_long. The contract example for sourceLanguage is de; the schema publishes no list of supported values and no format beyond the length limit.

Outputs: TranslationResponse contains the required string fields en, fr, es and it.

operationId Method and path Selection note
translatePartName GET /translation/translations Translate one permitted designation only.

Next steps: store or display the returned language field required by the caller. Do not concatenate prohibited content into one request.

15. Read the VDI 4081 catalogue

Use when: a caller needs the active catalogue version and entries.

Do not use when: the caller expects OE-to-VDI mappings from the catalogue endpoint.

Inputs: optional query limit (integer 1–500) and optional query offset (integer, minimum 0, allowed only together with limit); without limit the complete catalogue is returned. A malformed value returns HTTP 400 invalid_query_parameter.

Outputs: the closed VdiCatalogResponse always contains stand.catalogVersion, count (total entries before pagination), mainGroups[] and entries[]; page (limit, offset, returned, hasMore) is not a required field. Each entries[].code is a base code matching ^VDI4081_[0-9]+$; the full codes in vdi[] of GET /parts/oe/{oeNumber} match ^VDI4081_[0-9]+(?:_[0-9]+)?$.

operationId Method and path Selection note
getVdiCatalog GET /vdi Read the active catalogue; no OE assignments are returned.

Next steps: paginate with the returned page data when present. To obtain confirmed codes for an OE number, use GET /parts/oe/{oeNumber} and read vdi[]; do not join an OE number to catalogue entries through an invented endpoint.

16. Build and use a Client-scoped vehicle record

Use when: a Client already has a tapiId, needs a one-call vehicle intake from a registration document, or needs listing text based on documented vehicle facts.

Do not use when: tapiId belongs to another Client, when a response containing VIN or equipment is expected from the technical lookup, or when listing text must contain price, condition or value claims.

Inputs: technical lookup takes path tapiId (UUID). Intake requires the document URL fileUrl and accepts optional photoUrls[] (1–5 URIs of the same vehicle), country (two-letter code, default de) and includeOwner (default false; unless it is true, keeper data stays null). Listing composition takes path tapiId plus an optional body with quality (default standard), language=de|en|fr (default de) and notes (at most 500 characters).

Outputs: technical lookup returns tapiId and technical vehicle fields, but no VIN or equipment. Intake returns the closed VehicleIntakeResponse with the required fields format (contract example tapinoma.vehicle-intake.v1), registrationDocument, nullable vin, integer provider, nullable tapiId, nullable vehicle, nullable conditionReport, components and boolean complete; components.registrationDocument is delivered, components.vehicle is delivered|vin_not_readable|unavailable and components.conditionReport is delivered|failed|not_requested. Listing returns the closed VehicleListingResponse with the required fields format (a response-contract identifier to branch on; contract example tapinoma.vehicle-listing.v1), tapiId, language=de|en|fr, title (at most 80 characters), description, highlights[] (up to eight), documentedEquipmentCount and truncated.

operationId Method and path Selection note
getVehicleByTapiId GET /vehicles/{tapiId} Technical lookup included in the previously ordered VIN workflow for this Client; it is not a new vehicle-match order.
intakeVehicle POST /vehicles/intake Compose document extraction, immediate VIN matching and optional condition reporting.
composeVehicleListing POST /vehicles/{tapiId}/listing Compose text from facts documented for the Client-scoped vehicle reference.

Next steps: inspect components and complete rather than assuming every intake stage succeeded. Use a non-null intake tapiId for the two path-based vehicle operations; a null value is a terminal absence for those calls.

17. Match recall and safety measures

Use when: a caller needs a series-level match for one VIN already present through an earlier VIN retrieval, or needs to batch up to 100 OE positions with optional vehicle context.

Do not use when: the result would be represented as manufacturer confirmation that an individual vehicle or part is affected, repaired, safe for sale or compatible.

Inputs: vehicle matching takes path vin. Part matching requires positions[] with 1–100 closed position objects; each may carry oeNumber, a caller reference (at most 200 characters, returned unchanged) and a closed vehicle object with optional make, model and integer productionFrom/productionTo. A position needs at least oeNumber or vehicle.make, otherwise HTTP 400 invalid_recall_position; an empty list returns 400 invalid_positions and more than 100 positions return 400 too_many_recall_positions.

Outputs: vehicle matching returns vin, measures[], measureCount, registers[] (register=kba|eu_safety_gate|nhtsa, nullable dataStand, nullable measureCount) and notice with de, en and fr texts. Each measure carries reference, register, nullable publishedAt, manufacturer, tradeNames[], buildPeriod, stopDrive, nullable component, defect, remedy and match (confidence=strong|medium|weak, matchedOn[]). Part matching preserves the submitted order and returns per position nullable oeNumber, nullable normalizedOeNumber, nullable reference, status=matched|no_measures|unresolved, nullable unresolvedReason, measures[] and measureCount, plus positionCount, resolvedCount, registers[] and notice. An unresolvable VIN returns HTTP 404 vin_not_resolvable; a batch in which no position can be assigned to a manufacturer returns 404 recall_positions_unresolvable.

operationId Method and path Selection note
matchVehicleRecalls GET /recalls/vehicles/{vin} Return the documented series-level recall match.
matchPartRecalls POST /recalls/parts Batch match 1–100 ordered positions.

Next steps: retain each measure's match.confidence and match.matchedOn[], the registers[].dataStand values and notice with the result. Treat matched, no_measures and unresolved as distinct states. The contract's notice example states that only the manufacturer can confirm whether an individual vehicle is affected and whether a measure has been completed on it; obtain that confirmation from the manufacturer.

18. Assess visible vehicle or part condition

Use when: images must be converted into a damage description, a part grade, a structured vehicle condition report, an end-of-life classification, or visible licence-plate readings.

Do not use when: the caller needs a functional test, expert appraisal, repair estimate, residual-value calculation, keeper lookup, registration validation or facts not visible in the submitted images.

Inputs: every body is closed, requires imageUrls[] (URIs) and accepts optional quality=standard|enhanced|maximum (default standard). Damage description takes 1–5 imageUrls plus optional textQuality=notes|prose|expert (default notes). Part grading takes 1–3 imageUrls plus optional partType (at most 120 characters). Vehicle condition takes 1–8 imageUrls. End-of-life classification takes 1–10 imageUrls plus an optional closed vehicle object with vin, firstRegistration, mileageKm, inspectionValidUntil, marketValueEur, repairEstimateEur and damageDescription. Licence-plate reading takes 1–3 imageUrls.

Outputs: every response is closed and carries a required string format (contract examples tapinoma.damage-report.v1, tapinoma.part-quality.v1, tapinoma.condition-report.v1, tapinoma.elv-classification.v1, tapinoma.license-plate.v1). Damage description returns report (six fixed sections), format and truncated. Part grading returns format, gradable, nullable grade=A|B|C, nullable reason, partCategory, partName, criteria[] (key, rating, observation), reworkEffort, refinishEffort, limitations[], summary and visualOnly. Vehicle condition returns format, gradable, nullable grade=A|B|C, nullable reason, summary, zones[] (zone, findings[] with component, damageType, severity, observation), limitations[], imageCount and visualOnly. End-of-life classification returns format, classification=kein_altfahrzeug_verdacht|gutachten_empfohlen|altfahrzeug, nullable technicallyIrreparable and economicallyIrreparable, criteria[], economicAssessment, coverage (viewsCovered[], viewsMissing[]), vehicleObserved, limitations[], summary and visualOnly. Licence-plate reading returns format, imageCount, plateCount and plates[] (text, normalized, nullable country, confidence, position, obstructions[]).

operationId Method and path Selection note
describeDamageFromImages POST /vision/damage/describe Fixed six-section description of visible damage only.
gradePartQualityFromImages POST /vision/part/quality Visual `A
analyzePartFromImages POST /vision/part/analyze Combined identity, visible text and identifiers, visual condition and damage for one article; optional damage prose.
reportVehicleCondition POST /vision/condition-report Fixed-zone walk-around report and visual grade.
classifyEndOfLifeVehicle POST /vision/vehicle/elv-classification Classification from the submitted images and optional vehicle facts.
readLicensePlates POST /vision/license-plate Read visible characters only; no register lookup.

Next steps: persist limitations, coverage and visualOnly with the result. Route ungradable or incomplete evidence to a separate review process; no other public operation converts it into a verified technical fact.

19. Transform or generate publication images

Use when: a part or vehicle needs a generatively edited image on a white background, a part needs evidence-constrained generated views, a photographed part must be composited into a background, visible damage must be transferred to supplied views, or instance identifiers must be redacted.

Do not use when: background removal is expected to redact number plates or faces; generated views are expected to prove dimensions or identity without evidence; or an unverified redaction result may be published.

Combined part analysis: submit one article as imageUrls, with imagePackage=standard (default, up to 10 images) or extended (up to 25). Choose quality=standard|enhanced|maximum independently; all levels return the full analysis scope. Each original image is limited to 5,000,000 bytes; accepted formats are JPEG, PNG and static WebP over public HTTPS URLs. Working images retain aspect ratio and have at most 4,096 pixels on the longest edge. Original images are limited to 10,000 pixels per edge and 50 megapixels, subject to safe decoding limits. damageDescription=off (default) omits only additional prose; on requests it when assessable; auto delivers prose for confirmed visible damage and refunds the reserved description surcharge when none is delivered. The response includes identity, identifiers, visibleText, qualityAssessment, damages, images and damageDescription. sourceImages and images.index start at 1. Unknown values remain null or uncertain; optical grades do not verify function, fitment or structural safety. Explanations are returned in German. Set Idempotency-Key and allow at least 300 seconds for the synchronous response. The sandbox never fetches the submitted images and returns a synthetic unassessable example.

Inputs: cut-outs require only imageUrl; background=white and method=generate are the only supported choices and their defaults. Quality and part type are optional where declared. Quality governs generation quality, not a guaranteed resolution. Compare lettering, geometry, openings and wear against the original before publication; original pixels are not guaranteed unchanged. Generation requires oeNumber, with optional angles, finish/colour settings, quality, base-model flag, reference URLs and sourceMode=references_required|references_preferred|knowledge_only; it has no output body field. Compositing requires part and background URLs, damage transfer requires sources[] and targets[], and redaction requires 1–10 imageUrls; only those three request bodies expose output options. Each write operation's optional Idempotency-Key is a header, not an output property.

Outputs: cut-outs return the closed VisionCutoutResponse with the required fields format (contract example tapinoma.cutout.v1), subject=part|vehicle, quality, background=white, found, label, nullable imageUrl, nullable mediaType=image/png, nullable width and height, coverage (nullable areaShare, nullable touchesImageEdge, nullable cropped), sourcePixelsPreserved=false and limitations[]; they expose no generic asset or provenance object. Generated output has all three coverage values set to null; output dimensions are given by width and height. Generation returns 202 with jobId, status=queued, statusUrl, oeNumber, createdAt and retryAfterSeconds, plus Location and Retry-After headers. The job status always carries jobId, status=queued|running|succeeded|failed, statusUrl, oeNumber and createdAt; result and error are optional in the schema. For a usable succeeded state, locally require result with format=tapinoma.part-generation.v2, oeNumber, coverage, basis=reference_images|knowledge, synthetic=true, disclosure, finish, part, dimensions, materials, paintableSurface, baseModel, 1–6 views, identifierProtection, limitations and generatedAt; for failed, locally require error with code and message. Quarantine a state missing its corresponding result or error. Compositing returns format=tapinoma.part-composite.v1, one asset, partIdentityPreserved=true and limitations; damage transfer returns format=tapinoma.damage-transfer.v1, 1–6 assets, findings, notTransferred, limitations and visualOnly=true; redaction returns format=tapinoma.identifier-redaction.v1 and 1–10 assets. Every asset carries imageUrl, view, width, height, format=jpeg|png|webp, provenance and nullable expiresAt. An output that cannot be verified safely returns HTTP 422 with only error and message instead of an image. The documented codes are part_segmentation_failed and image_edit_unverified for compositing, damage_not_transferable and image_edit_unverified for damage transfer and identifier_redaction_unverified for redaction; treat every 422 from these three operations as a rejected output, whatever its code.

operationId Method and path Selection note
removePartBackground POST /vision/part/remove/bg Generatively edit the submitted part onto white; review details against the original.
removeVehicleBackground POST /vision/vehicle/remove/bg Generatively edit the submitted vehicle onto white; no plate or face redaction.
generatePartImagesFromOeNumber POST /vision/part/generate Start the asynchronous, evidence-labelled generation workflow.
getPartImageGenerationJob GET /vision/part/generation-jobs/{jobId} Poll only a part-image-generation job.
compositePartIntoBackground POST /vision/part/composite Place one photographed/cut-out part into one supplied background.
transferVisibleDamageToPartViews POST /vision/part/damage-transfer Transfer only reliably assignable visible findings to supplied target views.
redactPartIdentifiers POST /vision/identifiers/redact Apply and verify the documented public-asset identifier policy.

Next steps: for generation, follow statusUrl after Retry-After until succeeded or failed. Retain returned disclosure, provenance, evidence basis, limitations and expiry fields when present. When found=false, a job fails, or verification rejects an output, do not fabricate an asset URL or silently publish the source image.

20. Identify a dismantled part from available evidence

Use when: a caller needs to determine the catalogue number of one dismantled part from submitted numbers, label readings, descriptions and vehicle-related inputs.

Do not use when: the caller expects a new VIN lookup, wants an inferred number, or would treat multiple candidates as one confirmed part.

Inputs: the closed JSON body has no required field and may contain vin (3–17 characters, ^[A-HJ-NPR-Za-hj-npr-z0-9]{3,17}$), manufacturer (1–100 characters), customerOeNumbers[] (up to 20 strings of 1–128 characters), labelReadings[] (up to 20 closed objects, each with an optional open extractAll object and optional numbers[] of up to 20 strings of 1–128 characters) and descriptions[] (up to 10 strings of 1–160 characters).

Outputs: PartIdentifyResponse documents nine required fields: status=matched|candidates|unresolved, nullable oeNumber, nullable normalizedOeNumber, nullable tapiGenArt (^TGA-[0-9]{6}$), nullable source (documented values customer, label, vin_parts_list), nullable confidence (0–1), nullable manufacturer, nullable vinPart (name, number, nullable tapiGenArt, nullable category, nullable listPrice) and candidates[] (at most 10, each with name, number, nullable tapiGenArt, nullable category, nullable listPrice, score 0–1 and reasons[]). Only matched confirms exactly one catalogue number.

operationId Method and path Selection note
identifyPart POST /parts/identify Compare the supplied evidence and return the documented result.

Next steps: use normalizedOeNumber with the OE operations only when status=matched. Present candidates for review instead of selecting one automatically, and treat unresolved as a terminal no-match for the submitted evidence.

Operation coverage

The capability groups above cover the operations under paths in the published OpenAPI contract. A feature that is absent from this map and from the released OpenAPI paths object is not documented as a public capability.