---
title: "Delete a product permanently."
method: DELETE
path: "/api/v1/products/{id}"
tags: ["Products"]
---

# Delete a product permanently.

`DELETE /api/v1/products/{id}`

## Request

- Base URL: `https://app.tracepass.eu`
- URL: `https://app.tracepass.eu/api/v1/products/{id}`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.tracepass.eu/api/oauth/authorize`, token URL `https://app.tracepass.eu/api/oauth/token`, scopes: `passports:write`)

**Permanent and irreversible.** Removes the product row +
any uploaded documents whose only reference was this
product (documents linked to other products/passports
stay, just with `productId` unset), and the stored files
that belonged only to this product.

**Only products with ZERO passports of any status are
eligible** — including archived. The rule preserves audit
history: an archived passport carries the regulatory story
("we published this, then withdrew it") that would be
orphaned if the parent product disappeared.

**Paid-plan feature.** Returns 403 on Free plans; use the
archive endpoint instead.

Honours `Idempotency-Key`. No webhook.

## Headers

- `Idempotency-Key` string

## Response `200`

Permanently deleted; summary includes cascade counts.

- object
  - `message` string
  - `summary` object
    - `productId` string
    - `name` string
    - `deletedCounts` object
      - `documentRefsUnlinked` integer
      - `documentsDeleted` integer
      - `filesDeleted` integer

## Other responses

- `401`: Missing or invalid API key.
- `403`: Plan gate — hard-delete is paid-only.
- `404`: Resource doesn't exist or is in a different workspace.
- `409`: Product not eligible (any passports still reference it).
- `429`: Daily v1 write or passport-read budget exhausted. Resets at 00:00 UTC.

---

[API](https://skmtc.dev/tracepass/apis/tracepass-api.md) · [All operations](https://skmtc.dev/tracepass/apis/tracepass-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tracepass/apis/tracepass-api/revisions/60ddeb25638b?raw)
