# DELETE /v1/projects/:projectId/app-media/:mediaId (/docs/api/reference/app-media/delete-app-media)



<Endpoint method="DELETE" path="/v1/projects/:projectId/app-media/:mediaId" scope="projects:write" />

Soft-deletes the row. The R2 object is reaped by a background sweep; the asset disappears from `GET /app-media` and from content-generation queries immediately.

Scoped to the four partner-managed kinds (`logo`, `screenshot`, `demo-video`, `end-card`). Attempts to delete system-managed rows (auto-generated end-cards with `metadata.source = 'end-card-generator'`, internal-only kinds) return `404` to avoid leaking row existence across role boundaries.

## Response [#response]

<Response status="200" description="Deleted">
  ```json
  {
    "id": "med_01HZ...",
    "deleted": true
  }
  ```
</Response>

## Errors [#errors]

| Status | Code              | When                                                                                                     |
| ------ | ----------------- | -------------------------------------------------------------------------------------------------------- |
| 422    | `VALIDATION`      | `:mediaId` is not a valid `med_<uuid>` id.                                                               |
| 401    | `UNAUTHENTICATED` | Missing or invalid key.                                                                                  |
| 403    | `FORBIDDEN_SCOPE` | Key lacks `projects:write`.                                                                              |
| 404    | `NOT_FOUND`       | The media row doesn't exist, is already deleted, isn't in this project, or isn't a partner-managed kind. |

## Notes [#notes]

* **Logo replacement is automatic.** Uploading a new logo via [`POST /app-media`](/docs/api/reference/app-media/upload-app-media) soft-deletes any prior logo on the project. You don't need to DELETE the old one first.
* **Screenshots and demo videos are independently deletable.** Each is a separate row.
