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

# Delete a sales / lease / exchange

> Hard delete removes the row + storage files.

Permanently removes a listing owned by your organization. The listing
row is hard-deleted; every attached file is best-effort deleted from
Supabase Storage.

<Warning>
  **Irreversible**. For a recoverable removal, PATCH `status="archived"`
  instead the listing drops out of the active marketplace feed but the
  row and attachments stay.
</Warning>

## Headers

<ParamField header="Authorization" type="string" required>
  `Bearer tdao_live_…`
</ParamField>

<ParamField header="X-Organization-Id" type="string" required>
  Your organization's UUID.
</ParamField>

## Path parameters

<ParamField path="listing_id" type="string (UUID)" required />

## Auth requirements

Requires the **`seller`** capability. Cross-org access returns
**404 not\_found**.

## What happens, in order

1. Listing is fetched and ownership checked. Otherwise 404.
2. `listing.deleted` audit row written with key fields snapshotted in
   `previous_state` (title, msn, listing\_type, status, country).
3. Every URL in `documents[]` and `images[]` is parsed and best-effort
   deleted from Supabase Storage. Individual failures are logged but
   don't fail the call.
4. The listing row is hard-deleted from the database in the same
   transaction as the audit write.
5. `204 No Content` returned.

No other table foreign-keys back to `listings` (verified across all
current migrations), so there are no cascading dependents.

## Response

`204 No Content`. Empty body.

<RequestExample>
  ```bash curl theme={null}
  curl -X DELETE "$base_url/public/v1/sales-lease-exchange/$listing_id" \
    -H "Authorization: Bearer $api_key" \
    -H "X-Organization-Id: $org_id"
  ```

  ```python python theme={null}
  import requests
  resp = requests.delete(
      f"{base_url}/public/v1/sales-lease-exchange/{listing_id}",
      headers={"Authorization": f"Bearer {api_key}", "X-Organization-Id": org_id},
  )
  if resp.status_code == 204:
      print("Deleted")
  elif resp.status_code == 404:
      print("Not found (or not yours)")
  else:
      resp.raise_for_status()
  ```
</RequestExample>

<ResponseExample>
  ```http 204 No Content theme={null}
  HTTP/1.1 204 No Content
  ```

  ```jsonc 404 Not Found theme={null}
  { "detail": "Listing not found" }
  ```
</ResponseExample>

## Soft-delete alternative

```bash theme={null}
curl -X PATCH "$base_url/public/v1/sales-lease-exchange/$listing_id" \
  -H "Authorization: Bearer $api_key" \
  -H "X-Organization-Id: $org_id" \
  -H "Content-Type: application/json" \
  -d '{"status": "archived"}'
```

The listing's `status` becomes `archived`, it drops out of browse
results, but the row and attachments stay intact.

## See also

* [Update](/api-reference/listings/update) for the soft-delete-via-PATCH
  pattern.
* [Errors](/concepts/errors) for the `404` semantics.
