---
title: "Soft-delete a vehicle"
method: DELETE
path: "/v1/vehicles/{id}"
tags: ["Vehicles"]
---

# Soft-delete a vehicle

`DELETE /v1/vehicles/{id}`

## Request

- Base URL: `https://api.officina.it`
- URL: `https://api.officina.it/v1/vehicles/{id}`
- Auth: HTTP bearer

Marks the vehicle as deleted by stamping `deleted_at` with the
server clock. The row stays in the database; subsequent
GET/PATCH/DELETE all 404.

Returns the deleted resource (200) rather than 204 No Content
so the response shape is consistent across the API and the
mobile UI can render an undo banner with the timestamp.

## Response `200`

Vehicle soft-deleted. `deleted_at` is populated.

- Vehicle: A vehicle owned (or managed) by a workshop client. Multi-tenant: belongs to one company. `manufacturer_name` and `customer_name` are joined-in convenience fields populated by the repository so list rows can render `Fiat Panda — Mario Rossi` without a follow-up request. Rental fields are read-only on this resource. Mutate them via the dedicated rental setup flow.
  - `object` 'vehicle', required
  - `id` string, required
  - `license` string, nullable: License plate (regional format, free-form string).
  - `manufacturer_id` string, required
  - `manufacturer_name` string, required: Joined from the manufacturers table for display. Read-only; mutate via `manufacturer_id`.
  - `model` string, required
  - `variant` string, nullable
  - `vin` string, nullable: Vehicle Identification Number.
  - `transmission` string, nullable
  - `engine_power_kw` integer, nullable
  - `engine_displacement_ccm` integer, nullable
  - `engine_code` string, nullable: Codice motore. Stored trimmed and upper case (max 64 characters); an empty string or `null` clears it. When empty, officina.it may fill it from the vehicle's registration data. Shown in the app when `field_visibility.engine_code` is on.
  - `vehicle_weight_kg` integer, nullable
  - `engine_category` string, nullable
  - `registered_at` string, date-time, nullable
  - `comments` string, nullable
  - `customer_id` string, nullable
  - `customer_name` string, nullable: Joined from the owning customer's `full_name` for display. Read-only; mutate via `customer_id`.
  - `km` number, nullable: Most recently recorded odometer reading.
  - `km_registered_at` string, date-time, nullable
  - `last_inspection_at` string, date-time, nullable
  - `next_inspection_at` string, date-time, nullable
  - `next_appointment` string, date-time, nullable: Earliest upcoming calendar appointment for this vehicle, computed at read time.
  - `custom_fields` object, nullable: Raw stored values keyed by custom field definition `id` (see `VehicleCustomFieldValues` for the stored shapes). Includes hidden fields, and on older records keys of deleted definitions (dropped on the next PATCH that sends `custom_fields`).
  - `custom_field_values` object[]: Detail responses only. The company's visible custom field definitions (settings → Campi veicolo) resolved against this vehicle: configured order, display-ready names, "" when the vehicle has no value. Clients render these directly — no definition lookup needed.
    - `id` string, required
    - `name` string, required
    - `type` 'string' | 'integer' | 'datetime', required
    - `value` string, required
  - `documents` VehicleDocument[]: Detail responses only — the vehicle's Documenti Allegati. `url` is the authenticated download route (`/v1/vehicles/{id}/documents/{documentID}/download`).
    - `object` 'vehicle_document', required
    - `id` string, required
    - `name` string, required: Original file name.
    - `content_type` string, required
    - `description` string, nullable, required
    - `url` string, required
    - `file_size_bytes` integer, required
    - `created_at` string, date-time, required
  - `field_visibility` object: Detail responses only. The company's optional-field toggles (settings → Campi veicolo): the edit form hides — and omits from its PATCH — exactly what the web form hides. All true when never configured.
    - `km` boolean
    - `numero_telaio` boolean
    - `transmission` boolean
    - `engine_category` boolean
    - `engine_power_kw` boolean
    - `engine_displacement_ccm` boolean
    - `engine_code` boolean
    - `vehicle_weight_kg` boolean
    - `registration_date` boolean
    - `last_inspection_date` boolean
    - `next_inspection_date` boolean
  - `is_rental` boolean, required: Whether this vehicle is part of the workshop's rental fleet. Read-only here — managed by the rental setup flow.
  - `rental_daily_price_before_tax` number, nullable
  - `rental_daily_price_tax` number, nullable
  - `rental_daily_price_after_tax` number, nullable
  - `rental_vat_code` string, nullable
  - `rental_daily_discount_rate` number, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `deleted_at` string, date-time, nullable: Soft-deletion timestamp. Populated on the response from DELETE /v1/vehicles/{id}. Vehicles with a non-null deleted_at are not returned by list/detail endpoints — this field appears for the delete response only.

## Other responses

- `401`: Missing, malformed, expired, or wrong-audience bearer token.
- `402`: The company has no active subscription, or its plan does not include API access. API access is included in the Business and Illimitato plans.
- `403`: The authenticated user lacks the required permission.
- `404`: Resource does not exist OR belongs to a different company. The two cases are intentionally indistinguishable.
- `500`: Unhandled server error. Detail is logged, not exposed.

---

[API](https://skmtc.dev/officina/apis/officina-it-api.md) · [All operations](https://skmtc.dev/officina/apis/officina-it-api/llms.txt) · [OpenAPI document](https://skmtc.dev/officina/apis/officina-it-api/revisions/7da3fccfe551?raw)
