---
title: "Delete an email-report schedule (Snowflake native app only)."
method: DELETE
path: "/v1/dashboards/{id}/email-schedules/{sid}"
tags: ["dashboards"]
---

# Delete an email-report schedule (Snowflake native app only).

`DELETE /v1/dashboards/{id}/email-schedules/{sid}`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/dashboards/{id}/email-schedules/{sid}`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Permanently deletes the schedule and its recipients (cascade). Requires
`dashboard:write`. The append-only `dashboard.email` audit rows for any past
"Run now" send are in `audit_logs` and are NOT affected — deleting a schedule
never erases the record that a report was emailed.

> **THIS ROUTE ANSWERS `404` `feature-disabled` ONLY WHEN THE SURFACE IS
> OFF,** like every other verb under `/v1/dashboards/{id}/email-schedules`:
> all seven share the `editionCapabilities.unattendedSchedules` cell, and
> DVT-4490 ships it TRUE wherever `emailSchedule` is true — the normal
> Snowflake native-app case, answering normally here, not 404. 404 survives
> only with `DVT_UNATTENDED_SCHEDULES_ENABLED=false` on both dvt-api and
> dvt-engine, or on an edition where `emailSchedule` itself is false. When it
> does fire it precedes the path parse, so it is identical for a real
> schedule id and an invented one. Stored rows are unaffected either way.
> `POST /v1/dashboards/{id}/email` ("Email me this report now") remains the
> on-demand alternative regardless. Everything below describes the behavior
> every non-disabled install returns.

A plain row delete (DVT-4794, ADR-0069 Amendment 5 slice S3, D2): dvt
no longer runs any Snowflake statement to stop a task before removing
its own row, because dvt no longer creates that task in the first
place — a dispatcher-driven (or never-activated) row has no task to
stop. Deactivate is what clears the dispatcher pin, and is not
required before DELETE for one of these rows. No caller token is
required.

A LEGACY per-report task (`taskDriver` `task`) is the ONE exception
(DVT-4794 r1 F4): its task is still the consumer's own, exactly as
`GET .../setup` has always said — dvt does not own it and cannot
remove it for them — so deleting the row would orphan a live
Snowflake task with nothing left in dvt naming it. Refuses **409**
`schedule-deactivate-first` instead: `POST .../deactivate` first (it
clears the driver and returns `retiredTaskName`, the name to
`DROP TASK`), then delete.

## Response `204`

Deleted.

## Other responses

- `401`: Missing, invalid, or expired session.
- `403`: The caller's role does not permit this action.
- `404`: Resource does not exist.
- `409`: The row's `taskDriver` is the legacy `task`: its per-report task is still the consumer's own. Problem `type` is `https://docs.dvt.dev/errors/schedule-deactivate-first`.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
