> ## Documentation Index
> Fetch the complete documentation index at: https://api.visor.vin/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Customer-visible updates to the Visor Public API, MCP server, and developer docs.

<Update
  label="July 12, 2026"
  description="Cleaner option arrays on VIN and listing detail responses"
  tags={["API", "Non-breaking"]}
  rss={{
title: "Cleaner option arrays on VIN and listing detail responses",
description: "Options that share a display name are deduplicated, and conflicting interior/exterior color options are temporarily suppressed while upstream catalog data is remediated."
}}
>
  ## Changed

  * `options` arrays on `/v1/vins/{vin}`, `/v1/listings/{listing_id}`, and listing collections requested with `include=options` now deduplicate entries that share a display name, keeping the entry that carries an MSRP when available.
  * VIN and listing detail responses temporarily omit interior or exterior color options when a vehicle's catalog data contains more than one conflicting color of the same type; suppression will be retired once the upstream data remediation completes.

  ## Compatibility

  Non-breaking; no request changes required. `options` arrays may contain fewer, cleaner entries. Search filters and facet counts are unaffected.
</Update>

<Update
  label="July 7, 2026"
  description="Listings can be filtered and faceted by manufacturer model code"
  tags={["API", "MCP", "Non-breaking"]}
  rss={{
title: "Manufacturer model code filters and facets",
description: "Listing and facet requests now support model_code for manufacturer model-code matching."
}}
>
  ## Added

  * `/v1/listings`, dealer listing collections, and `/v1/facets` now support `model_code` as a listing filter.
  * `/v1/facets` now supports `facets=model_code` to discover manufacturer model-code buckets within a listing cohort.

  ## Compatibility

  Non-breaking; existing requests continue to work without changes.
</Update>

<Update
  label="July 4, 2026"
  description="MCP execute accepts JavaScript statement bodies"
  tags={["MCP", "Non-breaking"]}
  rss={{
title: "MCP execute accepts JavaScript statement bodies",
description: "Agents can now call MCP execute with either an async arrow function or plain async JavaScript statements."
}}
>
  ## Added

  * MCP `execute` now accepts either an async arrow function or a plain JavaScript statement body with `await` and `return`.
  * Async arrow functions with trailing semicolons are accepted, matching common generated code.

  ## Compatibility

  Non-breaking; existing async arrow execute calls continue to work.
</Update>

<Update
  label="July 2, 2026"
  description="Listing rows now support dealer postal codes and first-observed sync filters"
  tags={["API", "MCP", "Non-breaking"]}
  rss={{
title: "Listing postal codes and first-observed sync filters",
description: "Listing collection rows can include dealer postal_code and listed_at, and listing filters now support listed_after."
}}
>
  ## Added

  * `/v1/listings` and dealer listing collections now support `postal_code` and `listed_at` in `fields`.
  * `/v1/listings`, `/v1/dealers/{dealer_id}/listings`, and `/v1/facets` now support `listed_after=<ISO timestamp>` to filter listings first observed by Visor on or after that time.
  * Listing collections now support `sort=listed_at` and `sort=-listed_at`.

  ## Compatibility

  Non-breaking; existing requests continue to work without changes.
</Update>

<Update
  label="June 25, 2026"
  description="Listing availability status is selectable"
  tags={["API", "MCP", "Non-breaking"]}
  rss={{
title: "Listing availability status is selectable",
description: "Listing collection rows can now include availability_status when requested through fields."
}}
>
  ## Added

  * `/v1/listings` and dealer listing collections now support `availability_status` in `fields`, returning `stock`, `transit`, `build`, or `null` when requested.
  * MCP listing guidance now presents `availability_status` as both filterable and selectable, matching common agent usage.

  ## Compatibility

  Non-breaking; existing requests continue to work without changes.
</Update>

<Update
  label="June 17, 2026"
  description="Updated Claude MCP setup path"
  tags={["MCP", "Docs", "Non-breaking"]}
  rss={{
title: "Updated Claude MCP setup path",
description: "The Claude MCP setup guide now points individual users to Customize > Connectors."
}}
>
  ## Changed

  * Updated the Claude MCP setup guide to use **Customize → Connectors** for individual connector setup and member authentication. Team and Enterprise owners still add organization connectors from organization connector settings.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="June 17, 2026"
  description="Improved listing validation and facets"
  tags={["API", "Non-breaking"]}
  rss={{
title: "Improved listing validation and facets",
description: "Malformed dealer_id filters now return validation errors, and powertrain_type is available as a listing facet."
}}
>
  ## Fixed

  * `/v1/listings?dealer_id=...` now validates dealer IDs before searching, so malformed values return `400 validation_error` instead of `503 platform_error`.

  ## Added

  * `/v1/facets` now supports `powertrain_type` as a categorical facet for discovering available powertrain buckets within a listing cohort.

  ## Compatibility

  Non-breaking; existing requests continue to work without changes.
</Update>

<Update
  label="June 16, 2026"
  description="Added listing pricing detail on VIN and listing detail responses"
  tags={["API", "Non-breaking"]}
  rss={{
title: "Added listing pricing detail on VIN and listing detail responses",
description: "VIN and listing detail responses now include nullable pricing detail when available from supported providers."
}}
>
  ## Added

  * Added nullable `pricing` detail to `/v1/vins/{vin}` under `data.latest_listing.pricing` and to `/v1/listings/{listing_id}` under `data.pricing` when supported provider pricing details are available.
  * The existing `price` field is unchanged. `pricing.line_items` includes customer-facing amount, label, role, applicability, direction, row key/order, and subtype fields only.

  ## Compatibility

  Non-breaking; no request changes required. Listings without pricing detail return `pricing: null`.
</Update>

<Update
  label="June 14, 2026"
  description="Fixed sold listing detail lookups"
  tags={["API", "Non-breaking"]}
  rss={{
title: "Fixed sold listing detail lookups",
description: "Sold listing IDs returned from listing collections now resolve consistently through the listing detail endpoint."
}}
>
  ## Fixed

  * Fixed `/v1/listings/{listing_id}` for sold listing IDs returned from listing collections so eligible sold listings resolve consistently instead of returning a platform error or missing detail response.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="June 10, 2026"
  description="Clarified unknown VINs versus missing VIN status"
  tags={["Docs", "Non-breaking"]}
  rss={{
title: "Clarified unknown VINs versus missing VIN status",
description: "VIN docs now distinguish unknown VIN lookup misses from known VINs that are missing from active inventory."
}}
>
  ## Changed

  * Clarified VIN lookup docs: unknown VINs return `404 not_found_error`, while known VINs can return `status: "missing"` when they no longer appear in active inventory but have not been classified as sold.

  ## Compatibility

  Non-breaking documentation clarification; no request changes required.
</Update>

<Update
  label="June 10, 2026"
  description="Starter API Credit above $1 now expires 12 months after grant"
  tags={["API", "Billing", "Non-breaking"]}
  rss={{
title: "Starter API Credit above $1 now expires 12 months after grant",
description: "Self-serve Public API accounts keep a $1 starter baseline that never expires; the paid-plan starter boost above it expires 12 months after it is granted."
}}
>
  ## Changed

  * Starter API Credit follows your Visor plan: Free $1, Plus weekly $1, Plus monthly $10, Plus annual $50, Plus lifetime $100. The first $1 is a baseline that never expires.
  * The amount above the \$1 baseline is a one-time paid-plan starter boost. Unused boost credit expires 12 months after it is granted — one rule for every plan. Credit you have already spent is never clawed back, and purchased API Credit never expires.
  * The 12-month expiry also applies to starter credit granted before this change, measured from the original grant date.

  ## Compatibility

  Non-breaking for API requests; no client changes required. This changes promotional starter balance treatment only; purchased credit is unaffected.
</Update>

<Update
  label="June 9, 2026"
  description="Added data model and glossary guides"
  tags={["Docs", "Non-breaking"]}
  rss={{
title: "Added data model and glossary guides",
description: "The docs now include a customer-facing explanation of how Visor inventory data works and a glossary of public API terms."
}}
>
  ## Added

  * Added [How the Data Works](/docs/data-works), covering listings, VINs, dealers, inventory modes, deduplication, sold inventory, advertised pricing semantics, null handling, and recommended workflows.
  * Added [Glossary](/docs/glossary), defining public fields, filters, response concepts, usage terms, and vehicle-market vocabulary.
  * Clarified that sold inventory requires at least three days missing from the dealer inventory feed, `discount_from_msrp` uses combined MSRP, and `price` is the dealer's main advertised listing price.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="June 9, 2026"
  description="Expanded Public API onboarding guides and examples"
  tags={["Docs", "Non-breaking"]}
  rss={{
title: "Expanded Public API onboarding guides and examples",
description: "The docs now include dedicated authentication, filter/facet, error/retry, example workflow guides, and embedded OpenAPI examples for Public API users."
}}
>
  ## Added

  * Added dedicated guides for authentication and scopes, filter and facet discovery, API errors and retries, and common copyable workflows.
  * Added embedded request and successful response examples to each generated Public API reference operation.
  * Reorganized the Guides navigation into Start, Core concepts, Workflows, and Updates sections.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="June 9, 2026"
  description="Clearer facet guidance and stricter closed-vocabulary filters"
  tags={["API", "MCP", "Docs", "Non-breaking"]}
  rss={{
title: "Clearer facet guidance and stricter closed-vocabulary filters",
description: "Facet response paths are now documented for agents and API users, and closed-vocabulary filters now reject unsupported values instead of returning silent empty results."
}}
>
  ## Changed

  * MCP search results and public docs now call out the facet response envelope: categorical buckets are under `data.facets.<name>`, numeric buckets under `data.range_facets.<name>`, and stats under `data.stats.<name>`.
  * `inventory_type`, `exclude_inventory_type`, `keywords`, `exclude_keywords`, and listing `dealer_type` filters now validate their supported tokens. `inventory_type=cpo` is accepted as an alias for `certified`.
  * Listing and facet filters now support `powertrain_type`, `exclude_inventory_type`, `exclude_body_type`, `exclude_transmission`, and `exclude_drivetrain`.
  * Invalid VIN characters and malformed dealer IDs now return targeted `validation_error` responses instead of being conflated with missing resources or transient data errors.

  ## Compatibility

  Non-breaking for valid requests. Requests that previously relied on unsupported closed-vocabulary values returning empty result sets should remove the typo or discover open categorical values with `/v1/facets` before filtering.
</Update>

<Update
  label="June 8, 2026"
  description="Dealer visibility, profile batching, and listings search compatibility"
  tags={["API", "Deprecated", "Non-breaking"]}
  rss={{
title: "Dealer visibility, profile batching, and listings search compatibility",
description: "Dealer and inventory responses now consistently omit non-public sources, dealer search can fetch profiles by dealer ID list, and the deprecated listings search path now returns migration headers."
}}
>
  ## Added

  * `/v1/dealers?dealer_id=id1,id2` now returns matching dealer profiles for up to 100 comma-separated dealer IDs.

  ## Changed

  * Public dealer, listing, facet, VIN, and listing-detail responses now consistently omit dealer sources that are not eligible for Public API exposure.
  * MCP operation search now surfaces the dealer ID lookup filter for dealer profile batches.
  * Deprecated `/v1/listings/search` compatibility requests continue to execute and return migration headers. `per_page` maps to `limit`, and one-based `page` maps to `offset`.

  ## Compatibility

  Non-breaking; no request changes required for dealer visibility filtering or dealer ID lookup. New code should use `/v1/listings?limit=...&offset=...`; existing `/v1/listings/search` callers should migrate before the sunset date in the response headers.
</Update>

<Update
  label="June 6, 2026"
  description="MCP usage summary and listing response guidance"
  tags={["MCP", "API", "Non-breaking"]}
  rss={{
title: "MCP usage summary and listing response guidance",
description: "MCP agents can call usage summaries without an empty query object, and listing guidance now makes the collection response shape clearer."
}}
>
  ## Changed

  * MCP `visor.usage.summary()` now accepts an omitted query object.
  * Listing `fields` validation errors now clarify that `fields` controls response projection and list the supported listing fields.
  * MCP listing guidance now calls out `response.data` for rows and `response.pagination.total` for collection totals.

  ## Compatibility

  Non-breaking; existing requests continue to work.
</Update>

<Update
  label="June 5, 2026"
  description="MCP detail lookups and listing field guidance"
  tags={["MCP", "Docs", "Non-breaking"]}
  rss={{
title: "MCP detail lookups and listing field guidance",
description: "MCP agents can call detail lookups without empty options objects, and listing field guidance now distinguishes response fields from filters."
}}
>
  ## Changed

  * MCP `visor.vins.get(vin)` and `visor.listings.get(listingId)` now accept omitted options objects.
  * MCP search results and generated listing field docs now more clearly distinguish response `fields` from filters such as `availability_status`, `options_packages`, and `features`.

  ## Compatibility

  Non-breaking; existing requests continue to work.
</Update>

<Update
  label="June 3, 2026"
  description="Starter API Credit now follows subscription plan"
  tags={["API", "Billing", "Non-breaking"]}
  rss={{
title: "Starter API Credit now follows subscription plan",
description: "New self-serve Public API accounts now receive one-time starter API Credit based on the user's Visor subscription plan."
}}
>
  ## Changed

  * New self-serve Public API accounts receive one-time starter API Credit based on subscription plan: Free \$1, Plus weekly \$5, Plus monthly \$10, Plus annual \$50, and Plus lifetime \$100.

  ## Compatibility

  Non-breaking. Starter credit is promotional and does not count as Eligible Paid Credit for automatic Usage Tier promotion.
</Update>

<Update
  label="June 3, 2026"
  description="Expanded MCP agent setup guide"
  tags={["MCP", "Docs", "Non-breaking"]}
  rss={{
title: "Expanded MCP agent setup guide",
description: "The MCP setup guide now includes clearer setup paths for Claude, ChatGPT, Codex, Claude Code, OpenClaw, Hermes, generic MCP clients, and direct API usage."
}}
>
  ## Changed

  * The MCP setup guide has clearer app-specific connection steps, OAuth and bearer-token guidance, and examples for chat apps, coding agents, generic MCP clients, and API-based MCP usage.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="June 1, 2026"
  description="Price history entries include mileage"
  tags={["API", "Docs", "Non-breaking"]}
  rss={{
title: "Price history entries include mileage",
description: "Price history responses now include the observed odometer mileage for each price change when available."
}}
>
  ## Added

  * `include=price_history` responses now include `miles` on each price change event when odometer data is available.

  ## Compatibility

  Non-breaking; no request changes required. Existing clients can ignore the new nullable response field.
</Update>

<Update
  label="May 31, 2026"
  description="MCP search guidance and listing dealer type field"
  tags={["API", "MCP", "Docs", "Non-breaking"]}
  rss={{
title: "MCP search guidance and listing dealer type field",
description: "Listing responses can now request dealer_type, and MCP search results include richer parameter descriptions and response-total guidance."
}}
>
  ## Changed

  * `/v1/listings` and dealer listing collections now allow `fields=dealer_type` to return the listing dealer type.
  * MCP `search` results now include parameter descriptions and response notes, including where collection totals are returned.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="May 29, 2026"
  description="Self-serve API accounts start with starter credit"
  tags={["API", "Billing", "Non-breaking"]}
  rss={{
title: "Self-serve API accounts start with starter credit",
description: "New self-serve Public API accounts now receive a promotional 1.00 USD starter API Credit."
}}
>
  ## Added

  * New self-serve Public API accounts receive \$1.00 in promotional API Credit.

  ## Compatibility

  Non-breaking. Starter credit is promotional and does not count as Eligible Paid Credit for automatic Usage Tier promotion.
</Update>

<Update
  label="May 25, 2026"
  description="Dealer make filters use compatible slug matching"
  tags={["API", "Filters", "Non-breaking"]}
  rss={{
title: "Dealer make filters use compatible slug matching",
description: "Dealer search make filters now share the same compatible make slug matching used by listing and facet filters."
}}
>
  ## Changed

  * `/v1/dealers?make=...` now matches represented Dealer Makes with the same display-name and slug handling used by Listing filters.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="May 24, 2026"
  description="Model filters handle punctuation consistently"
  tags={["API", "Filters", "Non-breaking"]}
  rss={{
title: "Model filters handle punctuation consistently",
description: "Listing and facet filters now match model names with punctuation across active, historical, and sold inventory."
}}
>
  ## Changed

  * Make/model filters now match vehicle names with punctuation, symbols, or accents more consistently across public inventory queries.

  ## Compatibility

  Non-breaking; no request changes required.
</Update>

<Update
  label="May 23, 2026"
  description="MCP facet metric types include discount from MSRP"
  tags={["MCP", "Docs", "Non-breaking"]}
  rss={{
title: "MCP facet metric types include discount from MSRP",
description: "The Visor MCP execute type surface now advertises discount_from_msrp facet metrics, matching the existing public API facet contract."
}}
>
  ## Changed

  * MCP facet metric types and generated OpenAPI descriptions now include `discount_from_msrp`, matching the existing `/v1/facets` contract.

  ## Compatibility

  Non-breaking. Existing `/v1/facets` HTTP clients do not need to change.
</Update>

<Update
  label="May 22, 2026"
  description="MCP execute workflows pace and retry rate-limited API calls"
  tags={["MCP", "Rate limits", "Non-breaking"]}
  rss={{
title: "MCP execute workflows pace and retry rate-limited API calls",
description: "The Visor MCP server now supports larger execute workflows with bounded request pacing, 429 retry handling, and structured pause guidance."
}}
>
  ## Changed

  * Increased the MCP `execute` workflow ceiling from 10 to 50 underlying public API requests.
  * Added MCP-side pacing, bounded `429` retries, and `retry_after_seconds` guidance when the client needs to wait.

  ## Compatibility

  Non-breaking. Underlying public API calls still count against normal rate limits, metering, and monthly spend controls.
</Update>

<Update
  label="May 21, 2026"
  description="Availability status replaces public in-transit filtering"
  tags={["API", "Docs", "Breaking"]}
  rss={{
title: "Availability status replaces public in-transit filtering",
description: "Public listing and facet filters now use availability_status values stock, transit, and build instead of in_transit."
}}
>
  ## Changed

  * `/v1/listings` and `/v1/facets` now use `availability_status` values: `stock`, `transit`, and `build`.
  * Removed public `in_transit` filtering. Use `availability_status=stock` instead of `in_transit=false`, and `availability_status=transit,build` instead of `in_transit=true`.

  ## Compatibility

  Breaking. Update clients that send `in_transit`.
</Update>

<Update
  label="May 20, 2026"
  description="Hosted MCP server for agent access to the Visor Public API"
  tags={["MCP", "API", "Docs", "Non-breaking"]}
  rss={{
title: "Hosted MCP server for the Visor Public API",
description: "The Visor MCP server is now documented for OAuth and bearer-token access from agent hosts."
}}
>
  ## Added

  * Released the hosted MCP server at `https://mcp.visor.vin/mcp` with OAuth and bearer-token authentication.
  * Added `search` and `execute` tools for agent access to the Visor Public API.

  ## Compatibility

  Non-breaking. MCP calls map to the existing public `/v1` API contract and record normal public API Usage Events.
</Update>
